MPLAB-X is a full IDE and collection of toolchains for all the PIC micros.
The IDE itself isn't that wonderful, being written in JAVA, bit it's tolerable.
Personally I use the toolchains that come with MPLAB-X but use Anjuta for my IDE.
Specifically to resolve the question of binding variables to specific addresses in flash memory on the PIC18 with the C18 compiler, please reference the section "Pragmas" in the hlpC18ug.chm in the doc directory where the compiler is installed.
To do this you need to define a new "section" in memory and bind it to a start address so
#pragma romdata serial_no_section=0x1700
This creates a new section called "serial_no_section" that starts at address 0x1700 in flash (program) memory (because we defined "romdata" in the #pragma).
Directly after the #pragma line, define your variable(s) so:
#pragma romdata serial_no_section=0x1700
const rom int mySerialNumber = 0x1234;
#pragma romdata
Now you have 0x12 at address 0x1700 and 0x34 at address 0x1701 in memory (because PIC18 uses the little-endian model). The "const rom" ensure that the compiler knows that this is a const variable type, and that the variable lies in "rom" memory and thus need to be accessed via table read instructions.
The final #pragma romdata
statement ensures that any following variable declarations are linked to default memory sections as the linker sees fits rather than following on in the "serial_no_section" section.
Now all code can simply reference the variable "mySerialNumber", and you know exactly what address the serial number can be found at in memory.
Editing the HEX code can be a bit challenging as you need to calculate the checksum for each line you edit. I am working on a C++ class to decode and encode Intel HEX files which should make this easier, but it is not finished yet. Decoding files works, encoding again is not yet implemented. The project (if you are interested) is here https://github.com/codinghead/Intel-HEX-Class
Hope this helps
Best Answer
The first thing to do is to see what values the HEX file contains at what addresses. Here is the output of my HEX_DUMP program on your HEX file:
The last line is most likely the config word, which means this is for a traditional PIC 16. For those PICs, the HEX file addresses are doubled since each PIC address holds 14 bits and HEX files only hold 8 bits of data per address. The last line is therefore setting the PIC address 2007h to 3FB0h, which is exactly the kind of thing you'd expect the end of a HEX file for one of these PICs to contain.
The exact PIC 16 model is impossible to tell. Since we know it is a PIC 16, we can have MPLAB show us the dissassembled code:
To get this I set the processor in MPLAB to a 16F877, since that is a full memory traditional PIC 16.
Note that the instructions are quite plausible, although this is clearly written by someone that didn't really know what they were doing and probably didn't even use the linker.
The GOTO at 0 is probably attempting to jump 1 past the interrupt routine at 4, although that doesn't apparently exist since a GOTO 5 there makes no sense (at least to anyone that knows what they are doing, there is a lot of bad code out there). The next instruction attempts to set the bank, mess with TRISB, mess with the bank again, and jump to 15h.
I'm not going to try to decode the rest of this mess, but it seems quite certain we have the right processor architecture. We can't know the exact model because this would actually run on most basic PIC 16. If you decode the config word, you might get a clue to narrow down the model more, but I really don't think you can get to a exact model because this code will in fact run on a bunch of them.