Tweeted twitter.com/#!/StackReverseEng/status/490377784603455488
3 Added dumping tag
| link
2 Better usage of the wiki syntax
source | link

Good afternoon, sinceSince I love to play with the WinAPI or debugging in general, I decided to write a small unpacker for the open source PE executable packer UPX today (Windows version).

In order to accomplish this, I proceeded as followingfollow:

  • CreateProcessCreateProcess API all with DEBUG+DEBUG_ONLY_THIS_PROCESSDEBUG and DEBUG_ONLY_THIS_PROCESS flags.
  • GetThreadContextGetThreadContext API call in order to read value of EIPEIP.
  • ReadProcessMemoryReadProcessMemory API call loop searching for the last JMPJMP instruction.
  • Overwriting the E9E9 with CCCC in order to set an INT3 BreakpointINT3 breakpoint on the address.
  • Entering DebugEventDebugEvent loop waiting for the Breakpointbreakpoint. Once reached, reset byte back to E9E9, decrease EIPEIP by one and jump to the address (OEPOEP) of the target.

After reaching the OEPOEP, I proceed as follows in order to dump the process:

  • Read ImageBase, Base of code, ImageSize, ... from original PE headers
  • ReadProcessMemory(hProcess, header32.ImageBase, buffer, header32.SizeOfImage, bytes_read)ReadProcessMemory(hProcess, header32.ImageBase, buffer, header32.SizeOfImage, bytes_read)
  • Save buffer content to payload.bin, update the PE header of the file with new EntryPoint (OEPOEP) and set RawDataOffsetRawDataOffset and RawDataSizeRawDataSize of each section to its corresponding VirtualAddressVirtualAddress/VirtualSizeVirtualSize.

After creating the dump with fixed OEPOEP & RAW offsets/sizes for the sections, I fix the dump with ImpREC (right now manually, but I plan to use ImpREC.dllImpREC.dll or the ImpREC lite source in order to assemble everything in one tool at a later point).

The thing that confuses me though, is the fact, that the resulting binaries worked perfectly fine (exact match with the MUP) for one test case (a small hello world fasm application) and my dump file was exactly the same I had received through OllyDump, but when I tried to do the same unpacking with an UPX packed version of putty.exeputty.exe, my dumped memory varied from the one OllyDump had dumped starting at RAW offset 0x73970 0x73970 (exact match before that address). 

However - the file size is again the same one (and all bytes before that offset match), just after that certain address the bytes magically won't match anymore (they are still non-zero though).

I studied the source code in OllyDump.cOllyDump.c thoroughly regarding this difference, but as for now I didn't find my mistake... In some cases my dumps are equal to the ones generated by OllyDump and in some they aren't. Or is the mistake probably in my approach already?

Note: Source code omitted on purpose, since it's a few hundred lines long and super messy as for now. Can/will add further details if required or if I missed something, please just let me know in the comments. And sorry for my bad English.

Good afternoon, since I love to play with the WinAPI or debugging in general I decided to write a small unpacker for the open source PE executable packer UPX today (Windows version).

In order to accomplish this, I proceeded as following:

  • CreateProcess API all with DEBUG+DEBUG_ONLY_THIS_PROCESS flags
  • GetThreadContext API call in order to read value of EIP
  • ReadProcessMemory API call loop searching for the last JMP instruction
  • Overwriting the E9 with CC in order to set an INT3 Breakpoint on the address
  • Entering DebugEvent loop waiting for the Breakpoint. Once reached, reset byte back to E9, decrease EIP by one and jump to the address (OEP) of the target.

After reaching the OEP I proceed as follows in order to dump the process:

  • Read ImageBase, Base of code, ImageSize, ... from original PE headers
  • ReadProcessMemory(hProcess, header32.ImageBase, buffer, header32.SizeOfImage, bytes_read)
  • Save buffer content to payload.bin, update the PE header of the file with new EntryPoint (OEP) and set RawDataOffset and RawDataSize of each section to its corresponding VirtualAddress/VirtualSize.

After creating the dump with fixed OEP & RAW offsets/sizes for the sections, I fix the dump with ImpREC (right now manually, but I plan to use ImpREC.dll or the ImpREC lite source in order to assemble everything in one tool at a later point).

The thing that confuses me though, is the fact, that the resulting binaries worked perfectly fine (exact match with the MUP) for one test case (a small hello world fasm application) and my dump file was exactly the same I had received through OllyDump, but when I tried to do the same unpacking with an UPX packed version of putty.exe, my dumped memory varied from the one OllyDump had dumped starting at RAW offset 0x73970 (exact match before that address). However - the file size is again the same one (and all bytes before that offset match), just after that certain address the bytes magically won't match anymore (they are still non-zero though).

I studied the source code in OllyDump.c thoroughly regarding this difference, but as for now I didn't find my mistake... In some cases my dumps are equal to the ones generated by OllyDump and in some they aren't. Or is the mistake probably in my approach already?

Note: Source code omitted on purpose, since it's a few hundred lines long and super messy as for now. Can/will add further details if required or if I missed something, please just let me know in the comments. And sorry for my bad English.

Since I love to play with the WinAPI or debugging in general, I decided to write a small unpacker for the open source PE executable packer UPX today (Windows version).

In order to accomplish this, I proceeded as follow:

  • CreateProcess API all with DEBUG and DEBUG_ONLY_THIS_PROCESS flags.
  • GetThreadContext API call in order to read value of EIP.
  • ReadProcessMemory API call loop searching for the last JMP instruction.
  • Overwriting the E9 with CC in order to set an INT3 breakpoint on the address.
  • Entering DebugEvent loop waiting for the breakpoint. Once reached, reset byte back to E9, decrease EIP by one and jump to the address (OEP) of the target.

After reaching the OEP, I proceed as follows in order to dump the process:

  • Read ImageBase, Base of code, ImageSize, ... from original PE headers
  • ReadProcessMemory(hProcess, header32.ImageBase, buffer, header32.SizeOfImage, bytes_read)
  • Save buffer content to payload.bin, update the PE header of the file with new EntryPoint (OEP) and set RawDataOffset and RawDataSize of each section to its corresponding VirtualAddress/VirtualSize.

After creating the dump with fixed OEP & RAW offsets/sizes for the sections, I fix the dump with ImpREC (right now manually, but I plan to use ImpREC.dll or the ImpREC lite source in order to assemble everything in one tool at a later point).

The thing that confuses me though, is the fact, that the resulting binaries worked perfectly fine (exact match with the MUP) for one test case (a small hello world fasm application) and my dump file was exactly the same I had received through OllyDump, but when I tried to do the same unpacking with an UPX packed version of putty.exe, my dumped memory varied from the one OllyDump had dumped starting at RAW offset 0x73970 (exact match before that address). 

However - the file size is again the same one (and all bytes before that offset match), just after that certain address the bytes magically won't match anymore (they are still non-zero though).

I studied the source code in OllyDump.c thoroughly regarding this difference, but as for now I didn't find my mistake... In some cases my dumps are equal to the ones generated by OllyDump and in some they aren't. Or is the mistake probably in my approach already?

Note: Source code omitted on purpose, since it's a few hundred lines long and super messy as for now. Can/will add further details if required or if I missed something, please just let me know in the comments.

1
source | link

An issue when unpacking UPX

Good afternoon, since I love to play with the WinAPI or debugging in general I decided to write a small unpacker for the open source PE executable packer UPX today (Windows version).

In order to accomplish this, I proceeded as following:

  • CreateProcess API all with DEBUG+DEBUG_ONLY_THIS_PROCESS flags
  • GetThreadContext API call in order to read value of EIP
  • ReadProcessMemory API call loop searching for the last JMP instruction
  • Overwriting the E9 with CC in order to set an INT3 Breakpoint on the address
  • Entering DebugEvent loop waiting for the Breakpoint. Once reached, reset byte back to E9, decrease EIP by one and jump to the address (OEP) of the target.

After reaching the OEP I proceed as follows in order to dump the process:

  • Read ImageBase, Base of code, ImageSize, ... from original PE headers
  • ReadProcessMemory(hProcess, header32.ImageBase, buffer, header32.SizeOfImage, bytes_read)
  • Save buffer content to payload.bin, update the PE header of the file with new EntryPoint (OEP) and set RawDataOffset and RawDataSize of each section to its corresponding VirtualAddress/VirtualSize.

After creating the dump with fixed OEP & RAW offsets/sizes for the sections, I fix the dump with ImpREC (right now manually, but I plan to use ImpREC.dll or the ImpREC lite source in order to assemble everything in one tool at a later point).

The thing that confuses me though, is the fact, that the resulting binaries worked perfectly fine (exact match with the MUP) for one test case (a small hello world fasm application) and my dump file was exactly the same I had received through OllyDump, but when I tried to do the same unpacking with an UPX packed version of putty.exe, my dumped memory varied from the one OllyDump had dumped starting at RAW offset 0x73970 (exact match before that address). However - the file size is again the same one (and all bytes before that offset match), just after that certain address the bytes magically won't match anymore (they are still non-zero though).

I studied the source code in OllyDump.c thoroughly regarding this difference, but as for now I didn't find my mistake... In some cases my dumps are equal to the ones generated by OllyDump and in some they aren't. Or is the mistake probably in my approach already?

Note: Source code omitted on purpose, since it's a few hundred lines long and super messy as for now. Can/will add further details if required or if I missed something, please just let me know in the comments. And sorry for my bad English.