flat assembler
Message board for the users of flat assembler.
Index
> Windows > PE Header questions. |
Author |
|
mindcooler 19 Mar 2011, 11:53
What do you expect to load from your uninitialized struct?
If you wanted to load from your own runtime image, perhaps you meant something like this: Code: mov edi,[$400000+IMAGE_DOS_HEADER.e_lfanew] |
|||
19 Mar 2011, 11:53 |
|
Overflowz 19 Mar 2011, 12:02
how can I initialize it ? I'm trying to locate PE Header's RVA in current process but I don't know how.. I found this structure which are often used for such things..
|
|||
19 Mar 2011, 12:02 |
|
Overflowz 19 Mar 2011, 12:02
A bit problem here.. When I'm doing that, it show's me different location. I've opened 2 binaries in hex editor and PE headers has different image bases. How can I find PE header's RVA ?
|
|||
19 Mar 2011, 12:02 |
|
typedef 20 Mar 2011, 03:21
You'll need to open the exe you want to fill it with
Code: idosh IMAGE_DOS_HEADER CreateFile(...) ;If reading from disk mov [hFile],eax ReadFile,[hFile],idosh, sizeof.IMAGE_DOS_HEADER,... that will fill up the structure. Or if you know how, you can make a Device driver that contains your executable code and you can do IRP request to the device using CreateFile('\\.\yourDeviceDriver'), ReadFile,[hDevice],idosh,sizeof.IMAGE_DOS_HEADER,.... and then map that into memory and execute using CreateThread or setting next EIP pointer to it. |
|||
20 Mar 2011, 03:21 |
|
Overflowz 20 Mar 2011, 11:52
typedef
I don't know how to write drivers.. But I have still problem here. Watch this code, it's not working normally. Code: struct IMAGE_DOS_HEADER e_magic dw ? e_cblp dw ? e_cp dw ? e_crlc dw ? e_cparhdr dw ? e_minalloc dw ? e_maxalloc dw ? e_ss dw ? e_sp dw ? e_csum dw ? e_ip dw ? e_cs dw ? e_lfarlc dw ? e_ovno dw ? e_res dw ? e_oemid dw ? e_oeminfo dw ? e_res2 dw ? e_lfanew dd ? ends idosh IMAGE_DOS_HEADER ........ invoke CreateFile,fname,GENERIC_READ,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0 mov [hFile],eax invoke ReadFile,[hFile],idosh,sizeof.IMAGE_DOS_HEADER,rbytes,0 mov edi,[$400000+IMAGE_DOS_HEADER.e_lfanew] ;When I try idosh.e_lfanew, just watch in debugger what then happening. I can't explain. instead of mov edi,... it shows DB 8A or something.. |
|||
20 Mar 2011, 11:52 |
|
idle 20 Mar 2011, 14:23
can you tell the aim?
you have said "getting header's rva" there are lots of headers |
|||
20 Mar 2011, 14:23 |
|
typedef 20 Mar 2011, 16:23
Code: PUSH EBX EDI PUSH 0 PUSH FILE_ATTRIBUTE_NORMAL PUSH OPEN_EXISTING PUSH 0 PUSH 0 PUSH GENERIC_READ PUSH fname call [CreateFile] mov [hFile],eax PUSH 0 PUSH rbytes PUSH sizeof.IMAGE_DOS_HEADER PUSH idosh PUSH [hFile] CALL [ReadFile] MOV EBX,idosh MOV EDI,[EBX+IMAGE_DOS_HEADER.e_lfanew] POP EDI EBX try that..... Am at church right now |
|||
20 Mar 2011, 16:23 |
|
typedef 20 Mar 2011, 16:39
PS: e_lfanew points to another structure in this case. so you need to get that structure in order to get the entry point
Here, I found this.... I know you don't know C++; I'll translate it into ASM as soon as I get home http://www.rohitab.com/discuss/topic/33534-how-to-change-entry-point-of-pe-file/ The entry point of the executable is located at IMAGE_NT_HEADERS->OptionalHeader.AddressOfEntryPoint which you can change to suit your needs.The steps in getting this information is : 1 - You would read the file to an IMAGE_DOS_HEADER structure,then go on to get the NT header of the module.The offset for this structure is IMAGE_DOS_HEADER->e_lfanew. 2 - read and understand the MS PE file format which you can get the documentation for with a simple google search. Code: long SetFileEntryPoint(char *szFilename,long newEntryPoint) { IMAGE_DOS_HEADER *pHead; pHead = new IMAGE_DOS_HEADER; FILE *file = fopen(szFilename,"r+b"); if(!file) return -1; fread(pHead,sizeof(IMAGE_DOS_HEADER),1,file); if(pHead->e_magic != IMAGE_DOS_SIGNATURE) return -1; long peHeader = pHead->e_lfanew; long peOptHeader = peHeader + 4 + sizeof(IMAGE_FILE_HEADER); fseek(file,peOptHeader,SEEK_SET); IMAGE_OPTIONAL_HEADER *pOpt; pOpt = new IMAGE_OPTIONAL_HEADER; fread(pOpt,sizeof(IMAGE_OPTIONAL_HEADER),1,file); pOpt->AddressOfEntryPoint = newEntryPoint; fseek(file,peOptHeader,SEEK_SET); fwrite(pOpt,sizeof(IMAGE_OPTIONAL_HEADER),1,file); fclose(file); delete pOpt; delete pHead; return 1; } NOTE:I take no credit in this work |
|||
20 Mar 2011, 16:39 |
|
Overflowz 20 Mar 2011, 19:18
idle
I'm trying to understand how to modify program's header's in memory. For example, I want to open file, then store it in memory, get program's AddressOfEntrypoint(I Guess), then change it and save to disk. Or something like that. typedef Same problem.. I'd better wait for translate. Regards |
|||
20 Mar 2011, 19:18 |
|
typedef 20 Mar 2011, 23:25
@Overflows, sorry dude I am kind of busy writing my System Driver right now, so i just wrote it quickly......You can figure out some stuff if you think the results are not working. Use a debugger to look for changes.
I'm sorry if it doesn't work...maybe some one can help you out. I am a little busy right now Code: format PE GUI 4.0 include 'win32ax.inc' include 'api/user32.inc' include 'api/kernel32.inc' entry winMain ;____________________________________ IMAGE_DOS_SIGNATURE equ 5A4Dh ; MZ FILE_POINTER_MOVE_DISTANCE equ 4 + sizeof.IMAGE_FILE_HEADER IMAGE_NUMBEROF_DIRECTORY_ENTRIES equ 16 ;____________________________________ section '.idata' import data readable library \ kernel32,'kernel32.dll',\ user32 ,'user32.dll' section '.txt' code executable writable struct IMAGE_DATA_DIRECTORY VirtualAddress dd ?; DWORD Size dd ?; DWORD ends struct IMAGE_OPTIONAL_HEADER Magic dw ?; WORD MajorLinkerVersion db ?; BYTE MinorLinkerVersion db ?; BYTE SizeOfCode dd ?; DWORD SizeOfInitializedData dd ?; DWORD SizeOfUninitializedData dd ?; DWORD AddressOfEntryPoint dd ?; DWORD BaseOfCode dd ?; DWORD BaseOfData dd ?; DWORD ImageBase dd ?; DWORD SectionAlignment dd ?; DWORD FileAlignment dd ?; DWORD MajorOperatingSystemVersion dw ?; WORD MinorOperatingSystemVersion dw ?; WORD MajorImageVersion dw ?; WORD MinorImageVersion dw ?; WORD MajorSubsystemVersion dw ?; WORD MinorSubsystemVersion dw ?; WORD Win32VersionValue dd ?; DWORD SizeOfImage dd ?; DWORD SizeOfHeaders dd ?; DWORD CheckSum dd ?; DWORD Subsystem dw ?; WORD DllCharacteristics dw ?; WORD SizeOfStackReserve dd ?; DWORD SizeOfStackCommit dd ?; DWORD SizeOfHeapReserve dd ?; DWORD SizeOfHeapCommit dd ?; DWORD LoaderFlags dd ?; DWORD NumberOfRvaAndSizes dd ?; DWORD DataDirectory IMAGE_DATA_DIRECTORY ; IMAGE_NUMBEROF_DIRECTORY_ENTRIES ends struct IMAGE_DOS_HEADER e_magic dw ? e_cblp dw ? e_cp dw ? e_crlc dw ? e_cparhdr dw ? e_minalloc dw ? e_maxalloc dw ? e_ss dw ? e_sp dw ? e_csum dw ? e_ip dw ? e_cs dw ? e_lfarlc dw ? e_ovno dw ? e_res dw ? e_oemid dw ? e_oeminfo dw ? e_res2 dw ? e_lfanew dd ? ends struct IMAGE_FILE_HEADER Machine dw ?; WORD NumberOfSections dw ?; WORD TimeDateStamp dd ?; DWORD PointerToSymbolTable dd ?; DWORD NumberOfSymbols dd ?; DWORD SizeOfOptionalHeader dw ?; WORD Characteristics dw ?; WORD ends ;___________________________________________________ ; ENTRY POINT HERE ;___________________________________________________ ; ; ; ;___________________________________________________ proc winMain ;hinstance,hPrevhinstance,LPSTR,int ;ESP+8 hinstance ;ESP+C hPrevhinstance ;ESP+10 LPSTR lpCmdLine ;ESP+14 int nCmdShow PUSH EBP EDI EBX invoke CreateFile,'file.exe',GENERIC_ALL,FILE_SHARE_READ+FILE_SHARE_WRITE,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0 mov [hFile],eax test eax,eax jnz .err push 0 push rbytes push sizeof.IMAGE_DOS_HEADER push idosh push [hFile] call [ReadFile] ;jnz .err mov eax,idosh mov dx,IMAGE_DOS_SIGNATURE test dx,[eax+IMAGE_DOS_HEADER.e_magic] ; is this a valid header 'MZ' jnz .cont invoke MessageBox,0,'The specified file is not a valid PE file!','Error',MB_OK+MB_ICONERROR push [hFile] call [CloseHandle] push 0 call [ExitProcess] .cont: ;mov the structure again since we lost eax mov eax,[idosh] mov ebx,[eax+IMAGE_DOS_HEADER.e_lfanew] mov [peHdr],ebx ; we have the pointer to the PE structure here ;set the file pointer 4 bytes ahead of peHdr + the size of IMAGE_FILE_HEADER add ebx,[peHdr] add ebx,FILE_POINTER_MOVE_DISTANCE mov [peOptionalHdr],ebx ;get a copy of 32bit low order bits in ebx mov cx,bx mov [LowWord],cx ;get a copy of 32bit high order bits in ebx mov [HighWord],ebx shr ebx,16 push FILE_CURRENT ; Move from current position push ebx ; Distance to move, high order of a 32 bit value which is ebx shr 16 push cx ; Distance to move, low order of a 32 bit value which is bx=cx push [hFile] call [SetFilePointer] push 0 push rbytes push sizeof.IMAGE_OPTIONAL_HEADER push pOpt push [hFile] call [ReadFile] ;jnz .err ;change the entry point and write it back mov eax,[newEntryPoint] mov ebx,[pOpt] mov [ebx+IMAGE_OPTIONAL_HEADER.AddressOfEntryPoint],eax ;now set the file pointers back again(which means signed bits - ) and write starting from that pointer mov ax,-1 mul [LowWord] ; Lowword * -1 = -Loword (signed) mov eax,-1 mul [HighWord] push FILE_CURRENT ; Move from current position going back push [HighWord] ; Distance to move, high order of a 32 bit value which is ebx shr 16 push [LowWord] ; Distance to move, low order of a 32 bit value which is bx=cx push [hFile] call [SetFilePointer] ;write back push 0 push [bwriten] push sizeof.IMAGE_OPTIONAL_HEADER push pOpt push [hFile] call [WriteFile] test eax,eax jnz .err ;done here push [hFile] call [CloseHandle] POP EBX EDI EBP push 0 call [ExitProcess] .err: local buff:DWORD LEA EDX,[buff] call [GetLastError] push 0 push 0 push EDX push 0 push eax push 0 push FORMAT_MESSAGE_ALLOCATE_BUFFER+FORMAT_MESSAGE_FROM_SYSTEM call [FormatMessage] push MB_OK + MB_ICONINFORMATION push 0 push dword[buff] push 0 call [MessageBox] ret endp section '.data' data readable writable newEntryPoint dd 99999999;00408080 ; valid , you can invalidate it for some other purposes pOpt IMAGE_OPTIONAL_HEADER idosh IMAGE_DOS_HEADER hFile dd ? rbytes dd ? ; read bytes LowWord dw ? HighWord dd ? bwriten dd ?; peHdr dd ? ; pointer to PE Header ( e_lfanew ) peOptionalHdr dd ? ; It says optional but not really optional since its where we get the data from |
|||
20 Mar 2011, 23:25 |
|
Overflowz 21 Mar 2011, 09:25
typedef
Thanks for your support. It still doesn't work, I can't see changes in debugger.. I'll try to understand this myself. Thank you all. |
|||
21 Mar 2011, 09:25 |
|
vid 21 Mar 2011, 11:08
Overflow: Go over Iczlion's PE tutorial, it should give you infos you need in order to manipulate executables and/or dump them from memory.
|
|||
21 Mar 2011, 11:08 |
|
idle 21 Mar 2011, 12:11
modify victim.name
modify line #77 i did not check the code much Code: format pe gui section '' code executable import readable writable dd 0,0,0,rva kernel_name,rva kernel_table,\ 0,0,0,rva user_name,rva user_table,\ 0,0,0,0,0 kernel_name db 'kernel32.dll',0 align 4 kernel_table: CloseHandle dd rva CloseHandle_ CreateFileA dd rva CreateFileA_ ExitProcess dd rva ExitProcess_ ReadFile dd rva ReadFile_ SetFilePointer dd rva SetFilePointer_ WriteFile dd rva WriteFile_ dd 0 CloseHandle_ dw 0 db 'CloseHandle',0 CreateFileA_ dw 0 db 'CreateFileA',0 ExitProcess_ dw 0 db 'ExitProcess',0 ReadFile_ dw 0 db 'ReadFile',0 SetFilePointer_ dw 0 db 'SetFilePointer',0 WriteFile_ dw 0 db 'WriteFile',0 user_name db 'user32.dll',0 align 4 user_table: MessageBoxA dd rva MessageBoxA_ dd 0 MessageBoxA_ dw 0 db 'MessageBoxA',0 entry $ push 0 ;hTemplateFile push 0 ;dwFlagsAndAttributes push 3 ;dwCreationDistribution = OPEN_EXISTING push 0 ;lpSecurityAttributes push 1 ;dwShareMode = FILE_SHARE_READ push $8000'0000+$4000'0000 ;dwDesiredAccess = GENERIC_READ+WRITE push victim.name ;lpFileName call [CreateFileA] cmp eax,-1 je exit mov ebx,eax push 0 ;lpOverlapped push buffer.read ;lpNumberOfBytesRead push $40 ;nNumberOfBytesToRead = sizeof.IMAGE_DOS_HEADER push buffer.data ;lpBuffer push ebx ;hFile call [ReadFile] cmp [buffer.read],$40 jne leave_victim push 0 ;dwMoveMethod = FILE_BEGIN push 0 ;lpDistanceToMoveHigh push dword[buffer.data+$3c] ;lDistanceToMove = IMAGE_DOS_HEADER.OffsetToNewExeHEader push ebx ;hFile call [SetFilePointer] cmp eax,-1 je leave_victim push 0 buffer.read $38 buffer.data ebx call [ReadFile] cmp [buffer.read],$38 ;IMAGE_OPTIONAL_HEADER.ImageBase - IMAGE_NT_HEADERS + 4 jne leave_victim add dword[buffer.data+$34],$1000;IMAGE_OPTIONAL_HEADER.ImageBase + 4 push 1 0 (-4) ebx ;hfile, lDistanceToMove = back to IMAGE_OPTIONAL_HEADER.ImageBase, lpDistanceToMoveHigh, dwMoveMethod = FILE_CURRENT call [SetFilePointer] push 0 ;lpOwerlapped push buffer.read ;lpNumberOfBytesWritten push 4 ;nNumberOfBytesToWrite = sizeof.dword push buffer.data+$34 ;lpBuffer = IMAGE_OPTIONAL_HEADER.ImageBase push ebx ;hFile call [WriteFile] push 0 ;uType push 0 ;lpCaption push msg.base_updated ;lpText push 0 ;hWnd call [MessageBoxA] leave_victim: push ebx ;hObject call [CloseHandle] exit: push eax ;uExitCode call [ExitProcess] victim: .name db 'test\test.exe',0 msg: .base_updated db 'ImageBase updated',0 buffer: .read dd ? .data rb 512 |
|||
21 Mar 2011, 12:11 |
|
Overflowz 21 Mar 2011, 12:33
vid
idle Thanks for your support. I've got much information now. I'll study on it. Thanks again. |
|||
21 Mar 2011, 12:33 |
|
Overflowz 22 Mar 2011, 09:36
Last bit question. I don't understand the logic how people are getting PE header with this:
Code: add esi,[esi+0x3c] ;<-- PE header ESI points beginning of file and then getting PE header like this but I really don't understand how.. Someone explain me please. Thank you |
|||
22 Mar 2011, 09:36 |
|
vid 22 Mar 2011, 09:43
0x3c = IMAGE_DOS_HEADER.e_lfanew
Did you start studying Iczlion's tutorial? It really contains all the answers you seek. |
|||
22 Mar 2011, 09:43 |
|
Overflowz 22 Mar 2011, 11:58
vid
Yes but I don't understand, when I try IMAGE_DOS_HEADER.e_lfanew it says it's 0x24.. why ? and another thing, why I can't just do 'mov esi,[esi+0x3c]' ? |
|||
22 Mar 2011, 11:58 |
|
dancho 22 Mar 2011, 12:28
@Overflowz
if you count bytes to the e_lfanew element you will score 60 ( 0x3C ) , data at e_lfanew represents the offset to the IMAGE_NT_HEADERS , to the Signature to be more accurate , skiping ms-dos stub... |
|||
22 Mar 2011, 12:28 |
|
Overflowz 22 Mar 2011, 12:47
dancho
in above posts, I wrote IMAGE_DOS_HEADER structure. and when I'm accessing 'idosh.e_lfanew' it counts 0x24 but I know it is 0x3c and I don't understand why. Never mind, I'll try to figure out what's wrong there. Thanks! |
|||
22 Mar 2011, 12:47 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.