flat assembler
Message board for the users of flat assembler.

Index > Windows > 0xE9 opcode in Win32 PE files

Author
Thread Post new topic Reply to topic
AssemblerX86



Joined: 05 Sep 2015
Posts: 14
AssemblerX86 05 Sep 2015, 18:06
Hi Smile

I was wonder if it is possible to add a new code section (Similar to .text) to a .exe file and add executable code to it? Can I make a jump from a section to another using 0xE9 opcode (Or maybe 0xEA?)? For example if I put (0x66 0xE9 <4 byte address little-endian starting from next instruction>) in the start of .text, and the final address refers to the beginning of .text2 section, will it work?

I want to know this since I want to use a hex editor to play around with a certain program and want to make it jump to my custom .text2 section rather than the original one.

Do I need to make the JMP to the virtual address of the section (Once its loaded to memory)? Or physical address (Address in hard disk)?

Thank you!
Post 05 Sep 2015, 18:06
View user's profile Send private message Reply with quote
Foxxy



Joined: 14 Jul 2014
Posts: 42
Location: Somewhere over the rainbow...
Foxxy 06 Sep 2015, 01:15
I don't see why not, so long as the area is marked as executable. Don't take my word for it though, I don't do a lot of assembly work anymore.
Post 06 Sep 2015, 01:15
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20299
Location: In your JS exploiting you and your system
revolution 06 Sep 2015, 04:12
If the executable is signed then you will get verification errors unless you can re-sign it, or strip the existing signatures. Otherwise there should be no issue with adding code or sections to most executables, but check for UPX and other packers also.
Post 06 Sep 2015, 04:12
View user's profile Send private message Visit poster's website Reply with quote
catafest



Joined: 05 Aug 2010
Posts: 129
catafest 06 Sep 2015, 10:38
You really know what you want ?!
"Do I need to make the JMP to the virtual address of the section (Once its loaded to memory)? Or physical address (Address in hard disk)? "
assembly is not like any programming language ... !
Smile
Post 06 Sep 2015, 10:38
View user's profile Send private message Visit poster's website Yahoo Messenger Reply with quote
l_inc



Joined: 23 Oct 2009
Posts: 881
l_inc 06 Sep 2015, 13:55
AssemblerX86
Quote:
I was wonder if it is possible to add a new code section (Similar to .text) to a .exe file and add executable code to it?

Yes, in most cases it is. You only need to put the new section header at the end of the headers region, add new section data at the end of the executable, and fix some fields of the PE header and optional header: NumberOfSections, SizeOfCode, SizeOfImage and Checksum.

In some cases there are pitfalls, such as an overlay (each such case should be treated and analyzed individually), or no space for a new section header (the headers size can then be extended, but this would shift the file offsets of sections and therefore requires the executable to have relocations for proper modification), or a data directory inside the headers region could be using the space for the new section header. A cryptographic signature in a PE is in most cases not a problem, cause its verification is normally enforced only for some types of 32-bit drivers and for 64-bit drivers. This is provided the executable does not have its own internal integrity checks.

Quote:
Can I make a jump from a section to another using 0xE9 opcode (Or maybe 0xEA?)?

Yes, you can use both, but the former is more robust as it's base independent. $EA would require you to add a fixup entry for the offset part of the logical address inside the instruction. This instruction is normally not used in applications, cause there's normally only one accessible code segment.

Quote:
For example if I put (0x66 0xE9 <4 byte address little-endian starting from next instruction>) in the start of .text

The prefix $66 limits the immediate offset and the destination address to 2 bytes. You end up jumping into the unallocated region between 0 and $FFFF (unless you deliberately allocate virtual space there).

Quote:
Do I need to make the JMP to the virtual address of the section (Once its loaded to memory)?

Yes. The CPU executes your jump directly by knowing only the current virtual address and the instruction opcode: it doesn't go read files from the hard drive to find the destination address.
Quote:
Or physical address (Address in hard disk)?

It's called file offset. "Physical address" is a different unrelated concept.

_________________
Faith is a superposition of knowledge and fallacy
Post 06 Sep 2015, 13:55
View user's profile Send private message Reply with quote
AssemblerX86



Joined: 05 Sep 2015
Posts: 14
AssemblerX86 06 Sep 2015, 18:11
l_inc wrote:
AssemblerX86
Quote:
I was wonder if it is possible to add a new code section (Similar to .text) to a .exe file and add executable code to it?

Yes, in most cases it is. You only need to put the new section header at the end of the headers region, add new section data at the end of the executable, and fix some fields of the PE header and optional header: NumberOfSections, SizeOfCode, SizeOfImage and Checksum.

In some cases there are pitfalls, such as an overlay (each such case should be treated and analyzed individually), or no space for a new section header (the headers size can then be extended, but this would shift the file offsets of sections and therefore requires the executable to have relocations for proper modification), or a data directory inside the headers region could be using the space for the new section header. A cryptographic signature in a PE is in most cases not a problem, cause its verification is normally enforced only for some types of 32-bit drivers and for 64-bit drivers. This is provided the executable does not have its own internal integrity checks.

Quote:
Can I make a jump from a section to another using 0xE9 opcode (Or maybe 0xEA?)?

Yes, you can use both, but the former is more robust as it's base independent. $EA would require you to add a fixup entry for the offset part of the logical address inside the instruction. This instruction is normally not used in applications, cause there's normally only one accessible code segment.

Quote:
For example if I put (0x66 0xE9 <4 byte address little-endian starting from next instruction>) in the start of .text

The prefix $66 limits the immediate offset and the destination address to 2 bytes. You end up jumping into the unallocated region between 0 and $FFFF (unless you deliberately allocate virtual space there).

Quote:
Do I need to make the JMP to the virtual address of the section (Once its loaded to memory)?

Yes. The CPU executes your jump directly by knowing only the current virtual address and the instruction opcode: it doesn't go read files from the hard drive to find the destination address.
Quote:
Or physical address (Address in hard disk)?

It's called file offset. "Physical address" is a different unrelated concept.


What do you mean 0x66 limits the immediate offset to 2 bytes? Doesn't it make it DWORD (4 bytes) address rather than WORD?

I have done all of this, yet the executable crashes when I start it. I am calculating the virtual address using this equation:

Destination Section VA - (Current Instruction VA + 6)

*I am getting all virtual addresses of sections from the PE section table

When I disassemble it, the instruction is exactly where I want to jump:

JMP DWORD <destination address>

Even though it crashes. What if the code in that section requires data from .data? Would the address of the destination section cause troubles?

And by the way, the Checksum is set to 0x0000, what do I have to change in it?
Post 06 Sep 2015, 18:11
View user's profile Send private message Reply with quote
l_inc



Joined: 23 Oct 2009
Posts: 881
l_inc 06 Sep 2015, 19:50
AssemblerX86
Please, avoid quoting the whole post.
Quote:
What do you mean 0x66 limits the immediate offset to 2 bytes? Doesn't it make it DWORD (4 bytes) address rather than WORD?

Only if your code is 16-bit, i.e. if you're in real mode or in a 16-bit segment in protected/compatibility mode. As long as we are talking about PEs I assume you have 32-bit or 64-bit code, in which case the prefix makes it 2 bytes instead of 4. Although specially crafted PEs can natively execute 16 bit code in 32-bit Windows, I doubt this is your case.
Quote:
I have done all of this, yet the executable crashes when I start it

Well, then you did smth. wrong. Smile You may attach your modified executable.
Quote:
I am calculating the virtual address using this equation:

According to your "+6" I assume you still use the prefix $66. As I already said, this is wrong.
Quote:
What if the code in that section requires data from .data?

It can safely use that data as long as either the PE is not relocatable or all absolute references to the data have their corresponding fixups.
Quote:
And by the way, the Checksum is set to 0x0000, what do I have to change in it?

The checksum is 4 bytes long, not 2. But it's actually not critical for standard application PEs. You can safely leave zeroes in your case. If you want to assign the correct value, here is the algorithm (you may specify any PE instead of user32.dll):
Code:
format binary as "dll"

IDH.e_lfanew                    equ 3Ch
sizeof.Signature                equ 4h
sizeof.FileHeader               equ 14h
IOH.CheckSum                    equ 40h


PEFile: file "%WinDir%\system32\user32.dll"
PESize = $-PEFile

load PEHeader dword from PEFile + IDH.e_lfanew
PEHeader = PEFile + PEHeader

PEOptionalHeader = PEHeader + sizeof.Signature + sizeof.FileHeader

;set the checksum field to zero
store dword 0 at PEOptionalHeader + IOH.CheckSum

newCheckSum = 0
repeat PESize/4
        load buf dword from (%-1)*4
        newCheckSum = (newCheckSum + buf) and 0FFFFFFFFh + (newCheckSum + buf) shr 32
end repeat
newCheckSum = (newCheckSum shr 16) + (newCheckSum and 0FFFFh)
newCheckSum = newCheckSum and 0FFFFh + newCheckSum shr 16 + PESize

store dword newCheckSum at PEOptionalHeader + IOH.CheckSum    

_________________
Faith is a superposition of knowledge and fallacy
Post 06 Sep 2015, 19:50
View user's profile Send private message Reply with quote
Xorpd!



Joined: 21 Dec 2006
Posts: 161
Xorpd! 06 Sep 2015, 22:19
I've done this kind of stuff, but I used VirtualAlloc to get some memory marked writeable and executable at run time, and then played at will in that sandbox.
Post 06 Sep 2015, 22:19
View user's profile Send private message Visit poster's website Reply with quote
AssemblerX86



Joined: 05 Sep 2015
Posts: 14
AssemblerX86 26 Sep 2015, 00:39
Ok guys, what data do I have to change if I add an instruction (And shifting the rest of code to the right)? CALLs and JMPs only? And which opcodes? Immediate? Mod R/M? Relative? Direct?
Post 26 Sep 2015, 00:39
View user's profile Send private message Reply with quote
l_inc



Joined: 23 Oct 2009
Posts: 881
l_inc 26 Sep 2015, 00:54
AssemblerX86
All relative accesses to the shifted code from outside and from the shifted code to the outside. All absolute accesses to the shifted code from inside and outside of it. This includes modification not only of almost all kinds of instructions, but also data modification. Effectively you need to fully decompile and reverse engineer the program and then recompile it. For the general case you need an AI. Good luck with that. Smile

_________________
Faith is a superposition of knowledge and fallacy
Post 26 Sep 2015, 00:54
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.