Executable Packer (decompression/decryption stub) - c

I am working on an executable Packer & I have done compression & Encryption part so far. Now I have to store decompression/decryption stub/routine in the compressed file. My question is that will this stub be written in HEX code or I can place the assembly instruction directly ? If later is possible, then how ?

Creating a working packed binary requires:
modify the PE geometry
insert your code
Depending on your code size, you might want to use section padding, or to add your own section.
Then, to insert your code - as you seem to prefer direct ASM insertion - my suggestion would be to make the decryption code EIP-independent, then assemble it with something like YASM as pure code (-o), and include the code as assembled binary directly.
I wrote several mini-packers that might help as a starting reference, as they also 'insert' assembled code.

You have to have section with characteristic as "readable" & "writable" & "contains code" & "Is executable"
Address of Entry Point: 0x00019860
Section Header #1
Name: UPX0
Virtual Size: 0x00010000 (65536)
Virtual Address: 0x00001000
Size of Raw Data: 0x00000000 (0)
File Pointer to Raw Data: 0x00000400
File Pointer to Relocation Table: 0x00000000
File Pointer to Line Numbers: 0x00000000
Number of Relocations: 0
Number of Line Numbers: 0
Characteristics: 0xE0000080
Section contains uninitialized data.
Section is executable.
Section is readable.
Section is writeable.
Section Header #2
Name: UPX1
Virtual Size: 0x00009000 (36864)
Virtual Address: 0x00011000
Size of Raw Data: 0x00008A00 (35328)
File Pointer to Raw Data: 0x00000400
File Pointer to Relocation Table: 0x00000000
File Pointer to Line Numbers: 0x00000000
Number of Relocations: 0
Number of Line Numbers: 0
Characteristics: 0xE0000040
Section contains initialized data.
Section is executable.
Section is readable.
Section is writeable.
Section Header #3
Name: .rsrc
Virtual Size: 0x00001000 (4096)
Virtual Address: 0x0001A000
Size of Raw Data: 0x00000800 (2048)
File Pointer to Raw Data: 0x00008E00
File Pointer to Relocation Table: 0x00000000
File Pointer to Line Numbers: 0x00000000
Number of Relocations: 0
Number of Line Numbers: 0
Characteristics: 0xC0000040
Section contains initialized data.
Section is readable.
Section is writeable.
Just in short, UPX generates one section which contains compressed code and decompressor routine and second section which is uninitialized but is allowed to have writable and executable characteristic. The decompressor routine decompresses the code to the uninitialized section and continues with execution of the original entrypoint...

Related

Converting an prel31 address to the actual address from an .ARM.exidx section

I want to learn about ARM stack unwinding and for this reason, I took a closer look into the .ARM.exidx section of my binary. The binary was build using gcc for arm, little endian, for an Cortex M0 32bit.
As expected, I got the exidx table, here is an example I dumped with objdump:
8012d34 c09bff7f ab07b180 909cff7f a907b180 ................
8012d44 c09cff7f b0ab0e80 509eff7f b0ab0c80 ........P.......
8012d54 249fff7f b0aa0580 b49fff7f b0ab0880 $...............
8012d64 aca0ff7f b0ab1080 74a1ff7f b0ab0880 ........t.......
8012d74 dca1ff7f b0b0b080 e4a1ff7f aa03b180 ................
8012d84 34a2ff7f b0ab0880 20a3ff7f b0ab1280 4....... .......
8012d94 20a4ff7f b0b0b080 28a4ff7f b0b0a880 .......(.......
8012da4 44a4ff7f 01000000 10a6ff7f b0b0b080 D...............
As far as I understand is the first entry the call address of a function inside my programm (The ones that end in 0x7f) and are in the prel31 format to indicate the general model.
Now, my question is, how can I convert these addresses into the actual function addresses?
I found the conversion inside the unwind.h inside the linux for ARM kernel
/* Convert a prel31 symbol to an absolute address */
#define prel31_to_addr(ptr) \
({ \
/* sign-extend to 32 bits */ \
long offset = (((long)*(ptr)) << 1) >> 1; \
(unsigned long)(ptr) + offset; \
})
but I can not get the addresses from the exidx section to match up with the addresses I can look up inside the map file.
Should the addresses from the exidx match up with the from the map file or is there a misunderstanding on my side? If the should match up, how can I convert them?
See: Structure of ARM extab.
The exidx section is linked with the executable. The distance between the exidx and the code is important. You can get the linker to dump the table address. It is actually the 'binary offset'. For example,
10000: 8012d34 c09bff7f
Then you take 0x7fff9bc0, the 2nd little endian entry and run it through the macro.
Offset is 0xffff9bc0 -> 6440
So the binary offset is 10000-6440 -> 9bc0.
Unfortunately, your 'exidx' offset is probably not so nice as 0x10000. If you have a linker file, you can add padding to make it nice and easy to translate for an experiment.
The offset matters and this is what make a pointer relative of length 31 to an address (prel31addr).

PE file read one section in c [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 months ago.
Improve this question
I just read one section in PE file. I have output like this:
Section Info (1 of 6)
---------------------
Section Header name : .text
ActualSize of code or data : 0x49937
Virtual Address(RVA) : 0x1000
Size of raw data (rounded to FA) : 0x49a00
Pointer to Raw Data : 0x400
Pointer to Relocations : 0
Pointer to Line numbers : 0
Number of relocations : 0
Number of line numbers : 0
Characteristics : Contains executable code, Readable,
Section Info (2 of 6)
---------------------
Section Header name : .rdata
ActualSize of code or data : 0x1ed60
Virtual Address(RVA) : 0x4b000
Size of raw data (rounded to FA) : 0x1ee00
Pointer to Raw Data : 0x49e00
Pointer to Relocations : 0
Pointer to Line numbers : 0
Number of relocations : 0
Number of line numbers : 0
Characteristics : Contains initialized data, Readable,
I just want to read executable sections. For example, how can read .text section?
Caveat: Don't know for sure, but the following is based on some [obvious] deductions ...
In .text, the Pointer to Raw Data value is 0x400.
This [probably] isn't a valid memory address. So, it's [probably] a file offset (as this is what makes sense).
This is further supported by the fact that the .text section Size of raw data is 0x49a00.
Now, 0x400 + 0x49a00 --> 0x49e00 which is the Pointer to Raw Data value of the next section .rdata
So, if you seek the PE file to 0x400 and read 0x49a00 bytes, you'll be getting the contents of the .text section [as you desire]. That length is the rounded up length [to align to the next section's data], so a better length to read might be the ActualSize of code or data value of 0x49937
Side note: Although it's not a guarantee, the 0x400 offset of the .text section (the first section) data implies that the PE file header and all the [basic] section header structs fit in the first 0x400 (1024 decimal) bytes of the file. This is a reasonable assumption, given that PE is a simple format with a fixed number of section types (vs ELF that can have arbitrary/extensible sections).

What exactly does ". = 0x7c00" in a linker script do?

What exactly does ". = 0x7c00" in a linker script do?
More specifically, when I place . = 0x7c00 at the beginning of a linker script, why doesn't the resulting output file begin with 0x7c00 = 31,744 zeros?
I understand that when a PC boots, the BIOS places the 512 byte MBR at memory address 0x7c00. However, I am confused as to how exactly the linker's location counter affects how the output file is laid out.
(For context, I'm trying to thoroughly understand the sample code from the "x86 bare metal" project. https://github.com/cirosantilli/x86-bare-metal-examples. I've included the entire linker script below for context.)
SECTIONS
{
/*
We could also pass the -Ttext 0x7C00 to as instead of doing this.
If your program does not have any memory accesses, you can omit this.
*/
. = 0x7c00;
.text :
{
__start = .;
/*
We are going to stuff everything
into a text segment for now, including data.
Who cares? Other segments only exist to appease C compilers.
*/
*(.text)
/*
Magic bytes. 0x1FE == 510.
We could add this on each Gas file separately with `.word`,
but this is the perfect place to DRY that out.
*/
. = 0x1FE;
SHORT(0xAA55)
*(.stage2)
__stage2_nsectors = ABSOLUTE((. - __start) / 512);
. = ALIGN(512);
__end = .;
__end_align_4k = ALIGN(4k);
}
}
It looks like the ". = 0x7c00" is not meaning a length but an absolute address. It reads to me as 'set the current value of the special variable "." to be the hex value 0x7c00 and then it plans to use that address as an offset later in the script like with the . = ALIGN(512) it is also why it saves that address off as __start so it can then do math on the resulting image. If you manipulate . during the script so it points to the last chunk of memory added to the image then you can use it to determine the total size:
__stage2_nsectors = ABSOLUTE((. - __start) / 512);
in English would be
The difference between the starting place and wherever I ended divided by sector size.

Align a variable in memory with offset from power of two in memory

I would like to place a 2kB chunk of memory, aligned 16 bytes before a 1024 bytes alignment.
Platform : arm, bare metal, GNU toolchain. No need for portability
Can I do that with either GCC/attributes pragmas, ld custom linker script or any other solution ?
I would like to avoid wasting 1kB for that (basically placing a 3kB chunk of memory aligned at 1kB & adding 1024-16 bytes of padding).
Forcing a particular address to place the data is possible, but will ld be able to place variables before and after it (or is it just a way to put padding ? )
Context : buffer needs to be at 1k boundary by hardware design , but I'd like to add a bit of room before / after to be able to copy to this buffer with no bounds checking if my source is at most 16B wide.
edit: added example.
Let's say I have RAM starting at 0x2000000. I need a char buf[2048] be placed in it, at 1024*N-16 offset - ie (&buf[16])%1024==0 , hopefully without losing 1008 padding bytes.
(edit2)
So I'd like to have :
0x2000000 - some vars
0x2000010 - some other vars ...
0x2000100 - some other vars ...
0x20003F0 - char buf[2048] : here (int)&buf[16]%1024=0x2000400%1024==0
0x2000BF0 - some other vars ...
ALIGN(exp) is equivalent to (. + exp - 1) & ~(exp - 1). Of course, that expression only works if exp is a power of two. So you can't use ALIGN(), but you can write your own expression that does produce the result you want. Something like ((. + 1024 + 16 - 1) & ~(1024 - 1)) - 16 should do the trick. Plug in various values for . and you see it rounds up like you want.
The problem you'll have is that the linker will place every section you specified to be before your special section before it, and every section specified to be after it after it. It won't cleverly order the .data sections of different files to be before or after so as to produce the minimum amount of padding. It also won't re-order individual variables within an object file and section at all. If you are trying to pack as tightly as possible, I think you'll need to do something like:
.data : {
*(.about1008bytes)
. = ((. + 1024 + 16 - 1) & ~(1024 - 1)) - 16
*(.DMAbuf)
*(.data)
}
Use a section attribute to place your buffer in .DMAbuf and try to find close to but not more than 1008 bytes of other data variables and stick them in section .about1008bytes.
If you want to go crazy, use gcc -fdata-sections to place every data object in its own section, extract the section sizes with readelf, give that to a program you write to sort them for optimal packing that then spits out a chunk of linker script listing them in the optimal order.
You should define a specific section into your linker script, with the required alignment.
Looking at the man
ALIGN(exp)
Return the result of the current location counter (.) aligned to the next exp boundary. exp must be an expression whose value is a power of two. This is equivalent to
(. + exp - 1) & ~(exp - 1)
ALIGN doesn't change the value of the location counter--it just does arithmetic on it. As an example, to align the output .data section to the next 0x2000 byte boundary after the preceding section and to set a variable within the section to the next 0x8000 boundary after the input sections:
SECTIONS{ ...
.data ALIGN(0x2000): {
*(.data)
variable = ALIGN(0x8000);
}
... }
The first use of ALIGN in this example specifies the location of a section because it is used as the optional start attribute of a section definition (see section Optional Section Attributes). The second use simply defines the value of a variable. The built-in NEXT is closely related to ALIGN.
As an example you can define your section
SECTIONS
{
.myBufBlock ALIGN(16) :
{
KEEP(*(.myBufSection))
} > m_data
}
and into your code you can
unsigned char __attribute__((section (".myBufSection"))) buf[2048];
EDIT
SECTIONS
{
.myBufBlock 0x0x7FBF0 :
{
KEEP(*(.myBufSection))
} > m_data
}
and into your code you can
unsigned char __attribute__((section (".myBufSection"))) buf[16+2048+16];
To your DMA you can set the address &buf[16] that will be 1k aligned.

How to place variables in the access bank - PIC 18 MPASM linker script

I have a linker script which starts
INCLUDE 18f14K50_g.lkr
I want my interrupt service variables to go into the ACCESS bank. (My program's so small at the moment the whole lot can, but maybe in future...). So
SECTION NAME=VarsModemISR RAM=accessram
which results in:
MPLINK 4.39, Linker
Device Database Version 1.1
Copyright (c) 1998-2011 Microchip Technology Inc.
Error - section 'VarsModemISR' has a memory 'accessram' which is not defined in the linker command file.
Errors : 1
Examining the included file I believe it is. Either that or I'm working in extended mode and "gpre" is. I can use an #IFDEF to check, which I tried. The result, it was trying to use "accessram" not "gpre".
Maybe if I try defining the access bank explicitly by copying the line from the include file:
ACCESSBANK NAME=accessram START=0x0 END=0x5F
SECTION NAME=VarsModemISR RAM=accessram
This results in the error
MPLINK 4.39, Linker
Device Database Version 1.1
Copyright (c) 1998-2011 Microchip Technology Inc.
Error - duplicate definition of memory 'accessram'
Errors : 1
Which has me confused. According to the Assembler/Linker documentation I use SECTION with the RAM option, where RAM has previously been declared using ACCESSBANK, SHAREBANK or DATABANK. It should work.
Thanks
- Richard
There is really no need to change linker script, use default one!
Accessed file registers are available at any moment under PIC18 MCPUs.
Just declare variables in appropriate memory databank named ACCESSBANK which start at 0x00 and end at 0x60 address.
If you are using MPLAB than declare:
_Shared udata_acs 0 ;Shared memory file registers
IntReg1 res 1
IntReg2 res 1
;...
_UpperBank0 udata 060h ;Banked file memory registers
RegA res 1
;...
_Bank1 udata 0100h ;Banked file memory registers
N res 1
;...
Linker should automatically set the 'a' bit in code instruction for file register addresses, which are declared in ACCESSBANK.
I am using UDATA_ACS to declare the variables I want in access, so in modem.asm I have
; Variables for the interrupt handler - Access RAM
VarsModemISR UDATA_ACS
wave_index res 1 ; Index into the wave table for current sample
sample_period res 1 ; Sample period in use, TMR0 ticks
sample_count res 1 ; Amount of samples output since last bit boundary
fsrtmpl res 1 ; Temporary store for FSR
fsrtmph res 1 ; Temporary store for FSR
; Variables for the modem code - GPR0, non-Access
VarsModem UDATA
flag res 1 ; Counter for transmitting AX25 flags
bit res 1 ; Bit counter when transmitting a character
ch res 1 ; Current character being transmitted
...
My current linker script uses the supplied script, but defines my segments. I note that there's only one program page defined in the script, unlike on the PIC16s. No more PAGESEL?
INCLUDE 18f14K50_g.lkr
SECTION NAME=CodeModemISR ROM=page
SECTION NAME=CodeModem ROM=page
SECTION NAME=CodeWaveTable ROM=page
SECTION NAME=CodeEepromUtil ROM=page
SECTION NAME=VarsModem RAM=gpr0
SECTION NAME=VarsGPSState RAM=gpr0
SECTION NAME=CodeConfigEEPROM ROM=eedata
The resulting map contains the mappings I expect:
Hard coded locations as expected:
HighInterruptVector code 0x000008 program 0x000004
LowInterruptVector code 0x000018 program 0x000002
Movable locations packed in:
CodeModemISR code 0x00001a program 0x000028
CodeModem code 0x000042 program 0x0000fe
CodeWaveTable code 0x000140 program 0x000040
CodeMain code 0x000180 program 0x000054
EEPROM in the right place
CodeConfigEEPROM code 0xf00000 program 0x000044
And variables in ACCESSRAM and GP0
VarsModemISR udata 0x000000 data 0x000005
VarsModem udata 0x000060 data 0x000027
VarsGPSState udata 0x000087 data 0x00000e
There are more problems to solve, but they may be in other posts. I note that CodeWaveTable is taking 64 bytes so it's not closely packed. Solution - use CODE_PACK and now it's 32 bytes.

Resources