Log in

View Full Version : Reconstruct PE file from process memory (and save to disk)


Civa
July 11th, 2011, 03:34
Hello there,

First of all I would like to say Im at the new to RCE and I want to learn more and more.Im currently curious is there any way we can save module from process memory to disk (and that should be valid PE file) and later load it (maybe with some custom loader) into our process and examine functions (exports - also using custom "GetProcAddress"?Also I would like to let you guys know that Im not familiar with Python at all and I also examined couple of solutions written in P, so C/C++ would be nice!

Thanks,
C

rendari
July 11th, 2011, 05:28
We call the process "Dumping" a file, or "exe dumping", "executable dumping"... The tools are referred to as "Exe Dumpers". I suggest you look into a tool called PETools.

-rendari

Civa
July 11th, 2011, 09:31
Thank you very much for your response rendari!
I know for PE Tools alrady took a look at that.However I couldn't make it running on my Windows Server 2008 Enterprise machine, and as you already know its open source but in certain conditions ) Omg when I saw that I couldnt stop laughing...Correct me if Im woring but I have never seen (for almost 5 years of programming ) that someone is selling source code...

Nevertheless I alrady tried TitanEngine and seems I could dump quite valid PE file but when I opende it in bin editor there were a lot of differences...(also dumped PE file is bigger, can not be loaded via LoadLibrary, exports can not be obtained via GetProcAddress)...So there are many related problems...And guys from www.reversinglabs.com didnt validated my email (for signup) for almost 30 hours so I can not join their forum so Im stuck...Thats why Im here asking you guys for help.


Regards,
C

evlncrn8
July 11th, 2011, 14:13
The differences could be caused by multiple things..like...

¤ File alignment
¤ Extra section used for imports (rebuilding) eg: From using imprec
¤ Compression used (upx for example) where the dumped image will contain the decompressed code / data (if dumped at the right time etc..)
and many other reasons...

Just dumping from memory is not the end of the job..at best the dump may run on your pc or another with a different os..but when run on another os it will probably crash..
Nowadays with aslr etc theres a higher chance the dump probably won't work on the pc it was dumped from (especially after a reboot)..

Generally the step is..

¤ Dump
¤ Rebuild imports
¤ Clean up PE file (remove crap, align etc.. )

For other protections you might have to do more steps like..

¤ Dump and rebuild resources,
¤ Dump file(s) (if a file virtualiser is used.. Eg: molebox, starforce, securom dfa etc..) and maybe the same for any virtualised registry keys
¤ Rebuild functions that have been vm'ed
¤ Trip, catch and dump encrypted code functions (ccc's)
¤ Test, test and test some more...

Civa
July 11th, 2011, 18:10
evlncrn8 thank you very much for this response!! A lot of details I must admit!I will consider these steps and I would like to point out I was asking about a basic scenario (without packers etc.) some ordinary dll or executable found on system (to make things simpler).

Once again thanks for responses!!

Regards,
C

FrankRizzo
July 12th, 2011, 23:48
Civa, one thing that you might do to help us help you, is to run a tool like PEID, or DiE on the application that you want to dump, and report if it identifies any packers, or protections.

Then, you'll get more specialized answers.

Civa
July 13th, 2011, 07:00
Frank thanks for the reply!As I mentioned earlier I dont consider packed,compressed or special images.I just need step-by-step explanation how can process memory be dumped to hard disk (from process memory) assuming we are targeting some module (user32.dll for example) with valid base address and which have common data (very very basic scenario).

However I examined a lot of source code lately and I just cant understand why I can not dump sections properly to disk(except TitanEngine and thats complex code for me I just wanted to make things clear with more simpler code).

This is function which does dumping :

Code:
bool SaveToFile(const BE_MODULEINFO * modInfo,TCHAR * filename)
{
PIMAGE_NT_HEADERS pNTHeader = NULL;
ULONG_PTR plImageBase = (ULONG_PTR)modInfo->lpBaseOfDll;
TCHAR xml[MAX_PATH];
TCHAR dir[MAX_PATH];
char msg[4098];

// only dump executable images
__try {
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)plImageBase;
if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
return false;
}

pNTHeader = (PIMAGE_NT_HEADERS)((PBYTE)pDosHeader +
pDosHeader->e_lfanew);
if (pNTHeader->Signature != IMAGE_NT_SIGNATURE) {
return false;
}
} __except(EXCEPTION_EXECUTE_HANDLER) {
return false;
}

int numSections = pNTHeader->FileHeader.NumberOfSections;

PIMAGE_SECTION_HEADER section = (PIMAGE_SECTION_HEADER)(pNTHeader + 1);

// the section header ends here, from here to the start of the first section, we can fill zeros
PBYTE pLastSectionEnd = (PBYTE)(section + numSections);

ULONG file_alignment = pNTHeader->OptionalHeader.FileAlignment;

// write into a file
FILE* stream = fopen(filename, "w+b" );
if (stream == NULL ) {
return false;
}

sprintf(msg,"pbImageBase : 0x%x, first section starts at offset: 0x%x\n", plImageBase, section->PointerToRawData);
OutputDebugString(msg);

// write out header
DWORD headerLen = (DWORD)pLastSectionEnd-(DWORD)plImageBase;
DWORD numwritten = fwrite( (VOID*)plImageBase, 1, headerLen, stream );
if (numwritten != headerLen) {
sprintf(msg,"fwrite error, file: %s\n", filename);
OutputDebugString(msg);
}

// fill zeros upto the start of the first section
char zero = 0;
for (int i=headerLen; i<section->PointerToRawData; i++) { // roundUp(section->PointerToRawData, file_alignment)
fwrite( &zero, 1, 1, stream );
}

MEMORY_BASIC_INFORMATION mbi;
VirtualQuery((VOID*)plImageBase, &mbi, sizeof(mbi));
bool isMapped;

isMapped = (mbi.Type == MEM_IMAGE);

// write each section
//I just dont get this part here : What should be done to make these sections fixed
for (int i=0; i<numSections; i++) {
ULONG_PTR buf;
if (isMapped) {
buf = plImageBase + section->VirtualAddress;
} else {
buf = plImageBase + section->PointerToRawData;
}

sprintf(msg, "Writing section - Name: %s, buf: 0x%x, Size: 0x%x, PointerToRawData: 0x%x, Type: 0x%x\n",
section->Name, buf, section->SizeOfRawData, section->PointerToRawData, mbi.Type);

OutputDebugString(msg);

numwritten = fwrite((VOID*)buf, 1, section->SizeOfRawData, stream);

if (numwritten != section->SizeOfRawData) {
sprintf(msg,"fwrite error, file: %s\n", filename);
OutputDebugString(msg);
}

section ++;
}

//rest of code ommited for clarity....
}


If someone can help me with this and provide some explanations at least for fixing sections before I write them to file and also point what is here wrong and what is correct...I will try to find out myself how to fix import, export table after extracting takes a place in order to have image on disk which can be examined further.

Thank you very much!

Regards,
C

blabberer
July 13th, 2011, 13:07
a bare minimum exe executed and a bare minimum patch done to a bare minimum dump of process memory

exe used iczelions tut 02 msgbox.exe

dumper is .writemem in windbg dumped the whole memory range as is where is

patched some bare minimum bytes (3 bytes actually) (learn and seek what are they and why should they be patched) to make the exe run

Code:


civa:\>dir msg*
Volume in drive C has no label.
Volume Serial Number is 2C5E-367A

Directory of C:\Program Files\Debugging Tools for Windows (x86)\civa

07/13/2011 07:16 PM 2,560 msgbox.exe
07/13/2011 11:15 PM 16,384 msgbox_dump.exe
2 File(s) 18,944 bytes
0 Dir(s) 14,543,630,336 bytes free





Code:


C:\>cd "Program Files"

C:\Program Files>cd "Debugging Tools for Windows (x86)"

C:\Program Files\Debugging Tools for Windows (x86)>md civa

C:\Program Files\Debugging Tools for Windows (x86)>cd civa

C:\Program Files\Debugging Tools for Windows (x86)\civa>prompt civa:\$g

civa:\>dir /b

civa:\>copy c:\msgbox.exe .
1 file(s) copied.

civa:\>dir /b
msgbox.exe

civa:\>..\..\GnuWin32\bin\file msgbox.exe
msgbox.exe; PE32 executable for MS Windows (GUI) Intel 80386 32-bit

civa:\>msgbox.exe

civa:\>..\cdb.exe -c ".writemem msgbox_dump.exe 0x400000 L?4000;q" -pn msgbox.ex
e

Microsoft (R) Windows Debugger Version 6.12.0002.633 X86
Copyright (c) Microsoft Corporation. All rights reserved.

*** wait with pending attach
Symbol search path is: SRV*Z:\symbols\*
Executable search path is:
ModLoad: 00400000 00404000 C:\Program Files\Debugging Tools for Windows (x86)\
civa\msgbox.exe
ModLoad: 7c900000 7c9af000 C:\WINDOWS\system32\ntdll.dll
ModLoad: 7c800000 7c8f6000 C:\WINDOWS\system32\kernel32.dll
ModLoad: 7e410000 7e4a1000 C:\WINDOWS\system32\user32.dll
ModLoad: 77f10000 77f59000 C:\WINDOWS\system32\GDI32.dll
ModLoad: 5ad70000 5ada8000 C:\WINDOWS\system32\uxtheme.dll
ModLoad: 77dd0000 77e6b000 C:\WINDOWS\system32\ADVAPI32.dll
ModLoad: 77e70000 77f02000 C:\WINDOWS\system32\RPCRT4.dll
ModLoad: 77fe0000 77ff1000 C:\WINDOWS\system32\Secur32.dll
ModLoad: 77c10000 77c68000 C:\WINDOWS\system32\msvcrt.dll
(520.2a4): Break instruction exception - code 80000003 (first chance)
eax=7ffdf000 ebx=00000001 ecx=00000002 edx=00000003 esi=00000004 edi=00000005
eip=7c90120e esp=008bffcc ebp=008bfff4 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=0038 gs=0000 efl=00000246
ntdll!DbgBreakPoint:
7c90120e cc int 3
0:001> cdb: Reading initial command '.writemem msgbox_dump.exe 0x400000 L?4000;q
'
Writing 4000 bytes........
quit:

civa:\>dir /b
msgbox.exe
msgbox_dump.exe

civa:\>copy c:\gpatch.exe .
1 file(s) copied.

civa:\>dir /b
gpatch.exe
msgbox.exe
msgbox_dump.exe


civa:\>gpatch.exe msgbox_dump.exe /i445 /h"10"
GPATCH 2.0 - File Patching Utility
Copyright (C) 2002-2010 by Greg Wittmeyer - All Rights Reserved

Replaced 1 byte at index 445 in file "C:\Program Files\Debugging Tools for
Windows (x86)\civa\msgbox_dump.exe" with "►"



civa:\>gpatch.exe msgbox_dump.exe /i485 /h"20"
GPATCH 2.0 - File Patching Utility
Copyright (C) 2002-2010 by Greg Wittmeyer - All Rights Reserved

Replaced 1 byte at index 485 in file "C:\Program Files\Debugging Tools for
Windows (x86)\civa\msgbox_dump.exe" with " "

civa:\>gpatch.exe msgbox_dump.exe /i525 /h"30"
GPATCH 2.0 - File Patching Utility
Copyright (C) 2002-2010 by Greg Wittmeyer - All Rights Reserved

Replaced 1 byte at index 525 in file "C:\Program Files\Debugging Tools for
Windows (x86)\civa\msgbox_dump.exe" with "0"


civa:\>msgbox_dump.exe

civa:\>

Civa
July 13th, 2011, 15:15
Thanks blabberer !!

I Like the way you formatted console & debugger output ))
I will consider this of course!!

Cheers,

C

blabberer
July 14th, 2011, 00:57
Code:


C:\>systeminfo | findstr /b /i /c:"os name" /c:"os version"
OS Name: Microsoft Windows XP Professional
OS Version: 5.1.2600 Service Pack 3 Build 2600

C:\>C:\WINDOWS\system32\cmd.exe /k C:\WinDDK\7600.16385.1\bin\setenv.bat C:\WinD
DK\7600.16385.1\ fre x86 WLH
OACR monitor running already

C:\WinDDK\7600.16385.1>md civa & cd civa & prompt civa:\$g

civa:\>dir /b & copy f:\masm32\icztutes\tute02\test\msgbox.asm . & dir /b
1 file(s) copied.
msgbox.asm

civa:\>type msgbox.asm
.386
.model flat, stdcall
option casemap:none
include f:\masm32\include\windows.inc
include f:\masm32\include\kernel32.inc
include f:\masm32\include\user32.inc
includelib f:\masm32\lib\user32.lib
includelib f:\masm32\lib\kernel32.lib

.data
MsgCaption db "Iczelion's tutorial no.2",0
MsgBoxText db "Win32 Assembly is Great!",0

.code
start:
invoke MessageBox, NULL,addr MsgBoxText, addr MsgCaption, MB_OK
invoke ExitProcess,NULL
end start

civa:\>ml /c /coff msgbox.asm
Microsoft (R) Macro Assembler Version 9.00.30729.207 <--- brand new shiny ml
Copyright (C) Microsoft Corporation. All rights reserved.

Assembling: msgbox.asm
f:\masm32\include\windows.inc(17530) : error A2138:invalid data initializer get latest
windows.inc from hutch and replace old (windows.inc is now
2 files look at masm32 subforum


civa:\>ml /c /coff msgbox.asm
Microsoft (R) Macro Assembler Version 9.00.30729.207
Copyright (C) Microsoft Corporation. All rights reserved.

Assembling: msgbox.asm

civa:\>dir /b
msgbox.asm
msgbox.obj

civa:\>Link /SUBSYSTEM:WINDOWS /ALIGN:4096 /FILEALIGN:4096 "msgbox.obj"
Microsoft (R) Incremental Linker Version 9.00.30729.207
Copyright (C) Microsoft Corporation. All rights reserved.

LINK : warning LNK4108: /ALIGN specified without /DRIVER; image may not run

civa:\>dir /b
msgbox.asm
msgbox.exe
msgbox.obj

civa:\>dir msgbox.exe
Volume in drive C has no label.
Volume Serial Number is 9836-92E3

Directory of C:\WinDDK\7600.16385.1\civa

14/07/2011 11:11 16,384 msgbox.exe
1 File(s) 16,384 bytes
0 Dir(s) 3,541,442,560 bytes free

civa:\>msgbox.exe

civa:\>msgbox.exe

civa:\>f:\windbg\cdb.exe -c ".writemem msgbox_dump.exe 0x400000 L?4000
;q" -pn msgbox.exe

Microsoft (R) Windows Debugger Version 6.12.0002.633 X86
Copyright (c) Microsoft Corporation. All rights reserved.

*** wait with pending attach
Symbol search path is: SRV*F:\symbols*http://msdl.microsoft.com/download/symbols

Executable search path is:
ModLoad: 00400000 00404000 C:\WinDDK\7600.16385.1\civa\msgbox.exe
ModLoad: 7c900000 7c9b2000 C:\WINDOWS\system32\ntdll.dll
ModLoad: 7c800000 7c8f6000 C:\WINDOWS\system32\kernel32.dll
ModLoad: 64d00000 64d34000 C:\Program Files\Alwil Software\Avast5\snxhk.dll
ModLoad: 7e410000 7e4a1000 C:\WINDOWS\system32\user32.dll
ModLoad: 77f10000 77f59000 C:\WINDOWS\system32\GDI32.dll
ModLoad: 76390000 763ad000 C:\WINDOWS\system32\IMM32.DLL
ModLoad: 77dd0000 77e6b000 C:\WINDOWS\system32\ADVAPI32.dll
ModLoad: 77e70000 77f02000 C:\WINDOWS\system32\RPCRT4.dll
ModLoad: 77fe0000 77ff1000 C:\WINDOWS\system32\Secur32.dll
ModLoad: 5ad70000 5ada8000 C:\WINDOWS\system32\uxtheme.dll
ModLoad: 77c10000 77c68000 C:\WINDOWS\system32\msvcrt.dll
ModLoad: 74720000 7476c000 C:\WINDOWS\system32\MSCTF.dll
ModLoad: 77b40000 77b62000 C:\WINDOWS\system32\apphelp.dll
ModLoad: 755c0000 755ee000 C:\WINDOWS\system32\msctfime.ime
ModLoad: 774e0000 7761d000 C:\WINDOWS\system32\ole32.dll
ModLoad: 605d0000 605d9000 C:\WINDOWS\system32\mslbui.dll
ModLoad: 77120000 771ab000 C:\WINDOWS\system32\OLEAUT32.DLL
(c24.920): Break instruction exception - code 80000003 (first chance)
eax=7ffdf000 ebx=00000001 ecx=00000002 edx=00000003 esi=00000004 edi=00000005
eip=7c90120e esp=003effcc ebp=003efff4 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=0038 gs=0000 efl=00000246
ntdll!DbgBreakPoint:
7c90120e cc int 3
0:001> cdb: Reading initial command '.writemem msgbox_dump.exe 0x400000 L?4000;q
'
Writing 4000 bytes........
quit:

civa:\>dir /b
msgbox.asm
msgbox.exe
msgbox.obj
msgbox_dump.exe

civa:\>dir msgbox*.exe
Volume in drive C has no label.
Volume Serial Number is 9836-92E3

Directory of C:\WinDDK\7600.16385.1\civa

14/07/2011 11:11 16,384 msgbox.exe
14/07/2011 11:14 16,384 msgbox_dump.exe
2 File(s) 32,768 bytes
0 Dir(s) 3,541,426,176 bytes free

civa:\>fc /b msgbox.exe msgbox_dump.exe
Comparing files msgbox.exe and MSGBOX_DUMP.EXE
00002000: 76 12
00002001: 20 CB
00002002: 00 81
00002003: 00 7C
00002008: 5C EA
00002009: 20 07
0000200A: 00 45
0000200B: 00 7E

civa:\>msgbox_dump.exe

civa:\>

voila dump and run without any patch btw why does it run even when there are obvious differences ? find answer

civa:\>cd ..

civa:\>rd /s /q civa

civa:\>


have some more fun running a directly process memory dumped exe with no patches whatsoever

evlncrn8
July 16th, 2011, 04:00
Brand new shiny ml.exe would be v10 would it not? :-)

blabberer
July 22nd, 2011, 00:50
yep may be v10 didnt realise vs 2010 might have a newer ml wdk for win7 had 9

anyway

does any one know how to make vs 2008 emit e8 and jump table instead of ff15 type of call ??

see below for an example ml generates the inefficient type aka e8 and jump table
vs emits call dword aka ff15 type of calls

Code:


F:\windbg\>cdb -c "u 401000 la ;q" "f:\masm32\icztutes\tute02\msgbox.e
xe" | findstr 4010.
0:000> cdb: Reading initial command 'u 401000 la ;q'
00401000 6a00 push 0
00401002 6800304000 push offset image00400000+0x3000 (00403000)
00401007 6819304000 push offset image00400000+0x3019 (00403019)
0040100c 6a00 push 0
0040100e e807000000 call image00400000+0x101a (0040101a)
00401013 6a00 push 0
00401015 e806000000 call image00400000+0x1020 (00401020)
0040101a ff2508204000 jmp dword ptr [image00400000+0x2008 (00402008)]
00401020 ff2500204000 jmp dword ptr [image00400000+0x2000 (00402000)]
00401026 0000 add byte ptr [eax],al

F:\windbg\>cdb -c "u 401000 L10;q" "c:\Documents and Settings\Admin\My
Documents\Visual Studio 2008\Projects\VC8TEST\Release\VC8TEST.exe" | findstr 0
04010.
00401000 6a00 push 0
00401002 6800304000 push offset image00400000+0x3000 (00403000)
00401007 681c304000 push offset image00400000+0x301c (0040301c)
0040100c 6a00 push 0
0040100e ff1508204000 call dword ptr [image00400000+0x2008 (00402008)]
00401014 6a00 push 0
00401016 ff1500204000 call dword ptr [image00400000+0x2000 (00402000)]
0040101c cc int 3
0040101d 0000 add byte ptr [eax],al
0040101f 0000 add byte ptr [eax],al
00401021 0000 add byte ptr [eax],al
00401023 0000 add byte ptr [eax],al
00401025 0000 add byte ptr [eax],al
00401027 0000 add byte ptr [eax],al
00401029 0000 add byte ptr [eax],al
0040102b 0000 add byte ptr [eax],al

F:\windbg>


also how to tell vs to align the char[] at 1 byte instead of 4 bytes ?

notice 403019 and 40301c in listing

Code:


F:\windbg\>cdb -c "db 403000 l40 ;q" "f:\masm32\icztutes\tute02\msgbox
.exe" | findstr 4030.
0:000> cdb: Reading initial command 'db 403000 l40 ;q'
00403000 49 63 7a 65 6c 69 6f 6e-27 73 20 74 75 74 6f 72 Iczelion's tutor
00403010 69 61 6c 20 6e 6f 2e 32-00 57 69 6e 33 32 20 41 ial no.2.Win32 A
00403020 73 73 65 6d 62 6c 79 20-69 73 20 47 72 65 61 74 ssembly is Great
00403030 21 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 !...............

F:\windbg\>cdb -c "db 403000 L40;q" "c:\Documents and Settings\Admin\M
y Documents\Visual Studio 2008\Projects\VC8TEST\Release\VC8TEST.exe" | findstr
004030.
00403000 49 63 7a 65 6c 69 6f 6e-27 73 20 74 75 74 6f 72 Iczelion's tutor
00403010 69 61 6c 20 6e 6f 2e 32-00 00 00 00 57 69 6e 33 ial no.2....Win3
00403020 32 20 41 73 73 65 6d 62-6c 79 20 69 73 20 47 72 2 Assembly is Gr
00403030 65 61 74 21 00 00 00 00-00 00 00 00 00 00 00 00 eat!............

F:\windbg\>



the import section and .text section are fine

Code:


F:\windbg\>cdb -c "db 402000 La0;q" "c:\Documents and Settings\Admin\M
y Documents\Visual Studio 2008\Projects\VC8TEST\Release\VC8TEST.exe" | findstr
004020.
00402000 12 cb 81 7c 00 00 00 00-ea 07 45 7e 00 00 00 00 ...|......E~....
00402010 54 20 00 00 00 00 00 00-00 00 00 00 6a 20 00 00 T ..........j ..
00402020 08 20 00 00 4c 20 00 00-00 00 00 00 00 00 00 00 . ..L ..........
00402030 84 20 00 00 00 20 00 00-00 00 00 00 00 00 00 00 . ... ..........
00402040 00 00 00 00 00 00 00 00-00 00 00 00 76 20 00 00 ............v ..
00402050 00 00 00 00 5c 20 00 00-00 00 00 00 0e 02 4d 65 ....\ ........Me
00402060 73 73 61 67 65 42 6f 78-41 00 55 53 45 52 33 32 ssageBoxA.USER32
00402070 2e 64 6c 6c 00 00 19 01-45 78 69 74 50 72 6f 63 .dll....ExitProc
00402080 65 73 73 00 4b 45 52 4e-45 4c 33 32 2e 64 6c 6c ess.KERNEL32.dll
00402090 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................

F:\windbg\>cdb -c "db 402000 la0 ;q" "f:\masm32\icztutes\tute02\msgbox
.exe" | findstr 4020.
0:000> cdb: Reading initial command 'db 402000 la0 ;q'
00402000 12 cb 81 7c 00 00 00 00-ea 07 45 7e 00 00 00 00 ...|......E~....
00402010 54 20 00 00 00 00 00 00-00 00 00 00 6a 20 00 00 T ..........j ..
00402020 08 20 00 00 4c 20 00 00-00 00 00 00 00 00 00 00 . ..L ..........
00402030 84 20 00 00 00 20 00 00-00 00 00 00 00 00 00 00 . ... ..........
00402040 00 00 00 00 00 00 00 00-00 00 00 00 76 20 00 00 ............v ..
00402050 00 00 00 00 5c 20 00 00-00 00 00 00 9d 01 4d 65 ....\ ........Me
00402060 73 73 61 67 65 42 6f 78-41 00 75 73 65 72 33 32 ssageBoxA.user32
00402070 2e 64 6c 6c 00 00 80 00-45 78 69 74 50 72 6f 63 .dll....ExitProc
00402080 65 73 73 00 6b 65 72 6e-65 6c 33 32 2e 64 6c 6c ess.kernel32.dll
00402090 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................

F:\windbg>

disavowed
July 23rd, 2011, 14:50
Quote:
[Originally Posted by blabberer;90703]does any one know how to make vs 2008 emit e8 and jump table instead of ff15 type of call ??

http://msdn.microsoft.com/en-us/library/1b80826t(v=vs.80).aspx

blabberer
July 24th, 2011, 05:04
ha i presume my question was wrongly formulated should have been more clearer
like how to make cl.exe generate code that is same as ml.exe

that is make cl generate

Code:

0040100E E8 07000000 CALL <JMP.&USER32.MessageBoxA>
0040101A - FF25 08204000 JMP NEAR DWORD PTR DS:[<&USER32.MessageBoxA>]


instead of
Code:

0040100E FF15 08204000 CALL NEAR DWORD PTR DS:[<&USER32.MessageBoxA>]


without any hacks just by using available compiler and or linker switches only

Code:

copy paste to a .txt rename it to .bat update cdb.exe path and run in a new folder
del disa.exe & del disa.obj & del disa.c & PING 1.1.1.1 -n 1 -w 3000 >NUL
echo #include ^<windows.h^> >>disa.c
echo. >>disa.c
echo char Msg[24] = "Iczelion's tutorial no.2"; >>disa.c
echo char Title[] = "\0Win32 Assembly is Great!"; >>disa.c
echo. >>disa.c
echo __declspec(naked) int WINAPI WinMain( HINSTANCE hIstance, >>disa.c
echo HINSTANCE hPrevInstance, >>disa.c
echo LPSTR lpCmdLine, >>disa.c
echo int nShowCmd >>disa.c
echo ) >>disa.c
echo { >>disa.c
echo MessageBox(NULL,^&Title[1],Msg, MB_OK); >>disa.c
echo. >>disa.c
echo /* >>disa.c
echo MessageBox(NULL,Title,Msg, MB_OK); >>disa.c
echo ExitProcess(0); >>disa.c
echo */ >>disa.c
echo. >>disa.c
echo __asm >>disa.c
echo { >>disa.c
echo push MB_OK >>disa.c
echo push OFFSET Msg >>disa.c
echo push OFFSET Title [1] >>disa.c
echo push 0 >>disa.c
echo call MsgBox >>disa.c
echo push 0 >>disa.c
echo call ExitProc >>disa.c
echo MsgBox: >>disa.c
echo jmp dword ptr [MessageBox] >>disa.c
echo Exitproc: >>disa.c
echo jmp dword ptr [ExitProcess] >>disa.c
echo } >>disa.c
echo } >>disa.c

"c:\Program Files\Microsoft Visual Studio 9.0\VC\bin\vcvars32.bat" & del *.obj & cl /O2 /c disa.c & link /ENTRY:WinMain disa.obj user32.lib kernel32.lib & f:\windbg\cdb -c "u 401000 L10;q" disa.exe | findstr 00401. & pause


result
Code:

00401000 6a00 push 0
00401002 6800304000 push offset image00400000+0x3000 (00403000)
00401007 6819304000 push offset image00400000+0x3019 (00403019)
0040100c 6a00 push 0
0040100e ff1508204000 call dword ptr [image00400000+0x2008 (00402008)]
00401014 6a00 push 0
00401016 6800304000 push offset image00400000+0x3000 (00403000)
0040101b 6819304000 push offset image00400000+0x3019 (00403019)
00401020 6a00 push 0
00401022 e807000000 call image00400000+0x102e (0040102e)
00401027 6a00 push 0
00401029 e806000000 call image00400000+0x1034 (00401034)
0040102e ff2508204000 jmp dword ptr [image00400000+0x2008 (00402008)]
00401034 ff2500204000 jmp dword ptr [image00400000+0x2000 (00402000)]
0040103a 0000 add byte ptr [eax],al
0040103c 0000 add byte ptr [eax],al


now tell me how to do this without __asm emits etc

drizz
July 25th, 2011, 08:59
Quote:
[Originally Posted by evlncrn8;90661]Brand new shiny ml.exe would be v10 would it not? :-)
Nah, that would be JWASM ("http://www.japheth.de/JWasm.html") :-)

Quote:
[Originally Posted by blabberer]
does any one know how to make vs 2008 emit e8 and jump table instead of ff15 type of call ??
http://www.masm32.com/board/?topic=6519.msg86461#msg86461
I guess this is a hack . You could use your SED from gnuwin32 and hack it on the fly?

Quote:
[Originally Posted by blabberer]also how to tell vs to align the char[] at 1 byte instead of 4 bytes ?
In a structure? With "#pragma pack" http://msdn.microsoft.com/en-us/library/2e70t5y1(v=vs.80).aspx ( __declspec(align(x)) for "outer" alignment )

on-topic:

here's basic stuff that needs fixing (exe will execute on your machine):
Code:
int Fix()
{
#define DumpAlign(dwValue)\
((dwValue-1|(pNth->OptionalHeader.FileAlignment)-1)+1)
#define PAGE_SIZE 0x1000

PIMAGE_DOS_HEADER pDosh=pImage;
PIMAGE_NT_HEADERS pNth;
PIMAGE_SECTION_HEADER pFirstSech;

if (pDosh->e_magic!=IMAGE_DOS_SIGNATURE) return 0;
pNth=(PIMAGE_NT_HEADERS)((DWORD)pDosh+pDosh->e_lfanew);
if (pNth->Signature!=IMAGE_NT_SIGNATURE) return 0;
DWORD NumSec=pNth->FileHeader.NumberOfSections;

// fix size of headers
pNth->OptionalHeader.SizeOfHeaders=PAGE_SIZE;

// zero out directories
pNth->OptionalHeader.FileAlignment=PAGE_SIZE;
pNth->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress=0;
pNth->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size=0;
pNth->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress=0;
pNth->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size=0;

// fix raw=virtual
pFirstSech=(PIMAGE_SECTION_HEADER)((DWORD)pNth+sizeof(IMAGE_NT_HEADERS));
do {
pFirstSech->SizeOfRawData=DumpAlign(pFirstSech->Misc.VirtualSize);
pFirstSech->PointerToRawData=DumpAlign(pFirstSech->VirtualAddress);
pFirstSech++;
} while (NumSec--);

return 1;
}

blabberer
July 25th, 2011, 12:32
hi drizz

Quote:
In a structure? With "#pragma pack" http://msdn.microsoft.com/en-us/library/2e70t5y1(v=vs.80).aspx ( __declspec(align(x)) for "outer" alignment )


no not in a structure i meant

char blah[] = "foo"
char bloh[] = "goo"

the null termination at the end takes up more than one byte
Code:

00403010 69 61 6c 20 6e 6f 2e 32-00 57 69 6e 33 32 20 41 ial no.2.Win32 A
masm


Code:

00403010 69 61 6c 20 6e 6f 2e 32-00 00 00 00 57 69 6e 33 ial no.2....Win3
vc 2008


is ml.exe innefficient ?? is cl.exe extravagent or the obvious i am



edit

C:\Program Files\Microsoft SDKs\Windows\v7.1>grep -r "DECLSPEC_IMPORT __declspe
c(dllimport)" *.*
Include/Rpc.h:#define DECLSPEC_IMPORT __declspec(dllimport)
Include/WinNT.h:#define DECLSPEC_IMPORT __declspec(dllimport)

C:\Program Files\Microsoft SDKs\Windows\v7.1>

changing these two line will yield jump table ill check that out
so there is no legal way to do it with compiler

drizz
July 25th, 2011, 19:42
hi blabberer,

I did mention "__declspec(align())". "__declspec(align(1))" should work, at least it does for cl from vs2005, and cl from vctoolkit2003.

Quote:
[Originally Posted by blabberer;90731]
the null termination at the end takes up more than one byte
It's default aligning of variables to dword (or their recommended) boundary.

blabberer
July 26th, 2011, 08:52
Quote:
[Originally Posted by drizz;90734]hi blabberer,

I did mention "__declspec(align())". "__declspec(align(1))" should work, at least it does for cl from vs2005, and cl from vctoolkit2003.

It's default aligning of variables to dword (or their recommended) boundary.


you had mentioned it but i overlooked it as part of #pragma pack

yes it works in vs 2008 i got just 1 byte null terminator instead of dword align

also in an earlier post you mentioned about DECLSPEC_IMPORT and changing the line in Winnt.h

so i was just looking for linkages to it and i find you dont have to change include files

just have to define _the lib name_




C:\Program Files\Microsoft SDKs\Windows\v7.1\Include>grep -r -a3 -b3 "MessageBox
A(" WinUser.h
174441-WINUSERAPI
174453-int
174458-WINAPI
174466:MessageBoxA(
174480- __in_opt HWND hWnd,
174505- __in_opt LPCSTR lpText,
174534- __in_opt LPCSTR lpCaption,
--
175005-#ifdef UNICODE
175021- return MessageBoxW(
175046-#else
175053: return MessageBoxA(
175078-#endif
175086- hWnd,
175101- lpText,

C:\Program Files\Microsoft SDKs\Windows\v7.1\Include>grep -r -a3 -b3 "#define WI
NUSERAPI" WinUser.h
689-//
693-
695-#if !defined(_USER32_) <----
719:#define WINUSERAPI DECLSPEC_IMPORT
755-#define WINABLEAPI DECLSPEC_IMPORT
791-#else
798:#define WINUSERAPI
818-#define WINABLEAPI
838-#endif
846-

C:\Program Files\Microsoft SDKs\Windows\v7.1\Include>
[CODE]

so i defined it

[CODE]
#define _USER32_
#define _KERNEL32_
#include <windows.h>
__declspec(align(1)) char Msg[] = "Iczelion's tutorial no.2";
__declspec(align(1)) char Title[] = "Win32 Assembly is Great!";

int WINAPI WinMain(HINSTANCE hIstance,HINSTANCE hPrevInstance, LPSTR lpCmdLine,int nShowCmd)
{
MessageBox(NULL,Title,Msg, MB_OK);
ExitProcess(0);
}



and i got the jmp table like ml.exe but there is a small problem remaining still

WinMain is algned on DWORD boundary __declspec(align(1) dont work for Function Parameters and i have 2 0xcc's left in disassembly





image00400000+0x1000:
00401000 6a00 push 0
00401002 6800304000 push offset image00400000+0x3000 (00403000)
00401007 6819304000 push offset image00400000+0x3019 (00403019)
0040100c 6a00 push 0
0040100e e809000000 call image00400000+0x101c (0040101c)
00401013 6a00 push 0
00401015 e808000000 call image00400000+0x1022 (00401022)
0040101a cc int 3
0040101b cc int 3

0040101c ff2508204000 jmp dword ptr [image00400000+0x2008 (00402008)]
00401022 ff2500204000 jmp dword ptr [image00400000+0x2000 (00402000)]

blabberer
July 31st, 2011, 01:57
ok with this code disassembly (code section ) and strings (.data section) are same in both cl.exe and ml.exe

but in import table the name of dll is UPPERCASE in vc and LOWER CASE in ml who decides it
also hints for Same Function Are Different Who Decides it

Code:

#include <windows.h>
__declspec(align(1)) char Msg[] = "Iczelion's tutorial no.2";
__declspec(align(1)) char Title[] = "Win32 Assembly is Great!";


__declspec(naked) int WINAPI WinMain( HINSTANCE hIstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nShowCmd
)
{
__asm
{
push MB_OK
push OFFSET Msg
push OFFSET Title
push 0
call MsgBox
push 0
call ExitProc
MsgBox:
jmp dword ptr [MessageBox]
Exitproc:
jmp dword ptr [ExitProcess]
}
}

del frizz.exe & del frizz.obj
"c:\Program Files\Microsoft Visual Studio 9.0\VC\bin\vcvars32.bat" & cl /c /O1 frizz.c & link /ENTRY:WinMain frizz.obj user32.lib kernel32.lib


Code:

....\ ........MessageBoxA.USER32.dll....ExitProcess.KERNEL32.dll vc
....\ ........MessageBoxA.user32.dll..�.ExitProcess.kernel32.dll ml

drizz
August 7th, 2011, 06:09
hi, sorry for the late reply,

Quote:
[Originally Posted by blabberer;90772]but in import table the name of dll is UPPERCASE in vc and LOWER CASE in ml who decides it
also hints for Same Function Are Different Who Decides it

Code:

civa:\>type msgbox.asm
.386
.model flat, stdcall
option casemap:none
include f:\masm32\include\windows.inc
include f:\masm32\include\kernel32.inc
include f:\masm32\include\user32.inc
includelib f:\masm32\lib\user32.lib
includelib f:\masm32\lib\kernel32.lib
....


IIRC, the names are copied from lib files, hence don't use masm32 libs - use psdk libs(%VS%\VC\PlatformSDK\Lib\).
Also, specifying full paths in source is a bad practice, use "/LIBPATH" for linker and "/I" for compiler.

/I"f:\masm32\include" if you must... I prefer WinInc (http://www.japheth.de/WinInc.html)
/LIBPATH:"%VS%\VC\PlatformSDK\Lib"

Civa
August 7th, 2011, 16:07
Woooow guyz thank you very much for all answers ..Sorry I ve been absent for past few weeks so i didnt see all the stuff you rote here.I would review all the answers tommorrow and what to say TBHANK YOU ALL!

See ya...

Regards,
C

blabberer
August 17th, 2011, 00:33
like Drizz posted lib names and hints are copied from libs so by using psdk libs instead of masm libs the out put
of code section , .data section imports section become same with the following code for both masm 32 and vc 2008 executable

only pe headers are changed that is because of the Rich Signature

Code:

#include <windows.h>
__declspec(align(1)) char Msg[] = "Iczelion's tutorial no.2";
__declspec(align(1)) char Title[] = "Win32 Assembly is Great!";


__declspec(naked) int WINAPI WinMain( HINSTANCE hIstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nShowCmd
)
{
__asm
{
push MB_OK
push OFFSET Msg
push OFFSET Title
push 0
call MsgBox
push 0
call ExitProc
MsgBox:
jmp dword ptr [MessageBox]
Exitproc:
jmp dword ptr [ExitProcess]
}
}


Code:

compiled with

del frizz.exe & del frizz.obj
"c:\Program Files\Microsoft Visual Studio 9.0\VC\bin\vcvars32.bat" & cl /c /O1 frizz.c


linked with

Code:

link /ENTRY:WinMain frizz.obj C:\Progra~1\MI2578~1\Windows\v7.1\Lib\user32.lib C:\Progra~1\MI2578~1\Windows\v7.1\Lib\kernel32.lib


compare

Code:

00000080: 21 0F
00000081: 74 06
00000082: 82 67
00000084: 65 4B
00000085: 15 67
00000086: EC 09
00000088: 65 4B
00000089: 15 67
0000008A: EC 09
0000008C: 65 4B
0000008D: 15 67
0000008E: EC 09
00000090: 6C 42
00000091: 6D 1F
00000092: 7F 9A
00000094: 60 4E
00000095: 15 67
00000096: EC 09
00000098: 65 4B
00000099: 15 67
0000009A: ED 08
0000009C: 67 49
0000009D: 15 67
0000009E: EC 09
000000A0: 6C B7
000000A1: 6D 47
000000A2: 6F 1B
000000A4: 64 4A
000000A5: 15 67
000000A6: EC 09
000000A8: 6C 42
000000A9: 6D 1F
000000AA: 7D 98
000000AC: 64 4A
000000AD: 15 67
000000AE: EC 09
000000B4: 65 4B
000000B5: 15 67
000000B6: EC 09
000000D0: F4 F3 -> 4E4B4DF4 time date stamp Wed Aug 17 10:43:24 2011
000000D1: 4D 19
000000D2: 4B 40 -> Dll Charecteristics