2013년 10월 8일 화요일
2013년 10월 7일 월요일
pe
C:\work>peoep Hack.dll
Valid Dos Exe File
------------------
Dumping DOS Header Info....
---------------------------
Magic number : MZ(Mark Zbikowski)
Bytes on last page of file : 0x90
Pages in file : 0x3
Relocation : 0
Size of header in paragraphs : 0x4
Minimum extra paragraphs needed : 0
Maximum extra paragraphs needed : 0xffff
Initial (relative) SS value : 0
Initial SP value : 0xb8
Checksum : 0
Initial IP value : 0
Initial (relative) CS value : 0
File address of relocation table : 0x40
Overlay number : 0
OEM identifier : 0
OEM information(e_oemid specific) : 0
RVA address of PE header : 0xd0
===============================================================================
Valid PE file
-------------
Dumping COFF/PE Header Info....
--------------------------------
Signature : PE
Machine Architechture : Intel i386,i486,i586
Characteristics : Executable Image ,Dll file ,
Time Stamp : Sun Oct 06 19:14:48 2013
No.sections(size) : 5
No.entries in symbol table : 0
Size of optional header : 224
Dumping PE Optional Header Info....
-----------------------------------
Address of Entry Point : 0x12e0
Base Address of the Image : 0x10000000
SubSystem type : Windows GUI
Given file is a : PE32
Size of code segment(.text) : 163840
Base address of code segment(RVA) : 0x1000
Size of Initialized data : 36864
Base address of data segment(RVA) : 0x1000
Section Alignment : 0x1000
Major Linker Version : 6
Minor Linker Version : 0
Dumping Sections Header Info....
--------------------------------
Section Info (1 of 5)
---------------------
Section Header name : .text
ActualSize of code or data : 0x27590
Virtual Address(RVA) : 0x1000
Size of raw data (rounded to FA) : 0x28000
Pointer to Raw Data : 0x1000
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 5)
---------------------
Section Header name : .rdata
ActualSize of code or data : 0x1ee2
Virtual Address(RVA) : 0x29000
Size of raw data (rounded to FA) : 0x2000
Pointer to Raw Data : 0x29000
Pointer to Relocations : 0
Pointer to Line numbers : 0
Number of relocations : 0
Number of line numbers : 0
Characteristics : Contains initialized data, Readable,
Section Info (3 of 5)
---------------------
Section Header name : .data
ActualSize of code or data : 0x3f64
Virtual Address(RVA) : 0x2b000
Size of raw data (rounded to FA) : 0x3000
Pointer to Raw Data : 0x2b000
Pointer to Relocations : 0
Pointer to Line numbers : 0
Number of relocations : 0
Number of line numbers : 0
Characteristics : Contains initialized data, Readable, Writabl
e,
Section Info (4 of 5)
---------------------
Section Header name : .idata
ActualSize of code or data : 0x9ce
Virtual Address(RVA) : 0x2f000
Size of raw data (rounded to FA) : 0x1000
Pointer to Raw Data : 0x2e000
Pointer to Relocations : 0
Pointer to Line numbers : 0
Number of relocations : 0
Number of line numbers : 0
Characteristics : Contains initialized data, Readable, Writabl
e,
Section Info (5 of 5)
---------------------
Section Header name : .reloc
ActualSize of code or data : 0x15cc
Virtual Address(RVA) : 0x30000
Size of raw data (rounded to FA) : 0x2000
Pointer to Raw Data : 0x2f000
Pointer to Relocations : 0
Pointer to Line numbers : 0
Number of relocations : 0
Number of line numbers : 0
Characteristics : Contains initialized data, Readable,
===============================================================================
This Program is written by
K.Vineel Kumar Reddy.
III/IV IT Gayathri Vidya Parishad college of Eng.
C:\work>
Valid Dos Exe File
------------------
Dumping DOS Header Info....
---------------------------
Magic number : MZ(Mark Zbikowski)
Bytes on last page of file : 0x90
Pages in file : 0x3
Relocation : 0
Size of header in paragraphs : 0x4
Minimum extra paragraphs needed : 0
Maximum extra paragraphs needed : 0xffff
Initial (relative) SS value : 0
Initial SP value : 0xb8
Checksum : 0
Initial IP value : 0
Initial (relative) CS value : 0
File address of relocation table : 0x40
Overlay number : 0
OEM identifier : 0
OEM information(e_oemid specific) : 0
RVA address of PE header : 0xd0
===============================================================================
Valid PE file
-------------
Dumping COFF/PE Header Info....
--------------------------------
Signature : PE
Machine Architechture : Intel i386,i486,i586
Characteristics : Executable Image ,Dll file ,
Time Stamp : Sun Oct 06 19:14:48 2013
No.sections(size) : 5
No.entries in symbol table : 0
Size of optional header : 224
Dumping PE Optional Header Info....
-----------------------------------
Address of Entry Point : 0x12e0
Base Address of the Image : 0x10000000
SubSystem type : Windows GUI
Given file is a : PE32
Size of code segment(.text) : 163840
Base address of code segment(RVA) : 0x1000
Size of Initialized data : 36864
Base address of data segment(RVA) : 0x1000
Section Alignment : 0x1000
Major Linker Version : 6
Minor Linker Version : 0
Dumping Sections Header Info....
--------------------------------
Section Info (1 of 5)
---------------------
Section Header name : .text
ActualSize of code or data : 0x27590
Virtual Address(RVA) : 0x1000
Size of raw data (rounded to FA) : 0x28000
Pointer to Raw Data : 0x1000
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 5)
---------------------
Section Header name : .rdata
ActualSize of code or data : 0x1ee2
Virtual Address(RVA) : 0x29000
Size of raw data (rounded to FA) : 0x2000
Pointer to Raw Data : 0x29000
Pointer to Relocations : 0
Pointer to Line numbers : 0
Number of relocations : 0
Number of line numbers : 0
Characteristics : Contains initialized data, Readable,
Section Info (3 of 5)
---------------------
Section Header name : .data
ActualSize of code or data : 0x3f64
Virtual Address(RVA) : 0x2b000
Size of raw data (rounded to FA) : 0x3000
Pointer to Raw Data : 0x2b000
Pointer to Relocations : 0
Pointer to Line numbers : 0
Number of relocations : 0
Number of line numbers : 0
Characteristics : Contains initialized data, Readable, Writabl
e,
Section Info (4 of 5)
---------------------
Section Header name : .idata
ActualSize of code or data : 0x9ce
Virtual Address(RVA) : 0x2f000
Size of raw data (rounded to FA) : 0x1000
Pointer to Raw Data : 0x2e000
Pointer to Relocations : 0
Pointer to Line numbers : 0
Number of relocations : 0
Number of line numbers : 0
Characteristics : Contains initialized data, Readable, Writabl
e,
Section Info (5 of 5)
---------------------
Section Header name : .reloc
ActualSize of code or data : 0x15cc
Virtual Address(RVA) : 0x30000
Size of raw data (rounded to FA) : 0x2000
Pointer to Raw Data : 0x2f000
Pointer to Relocations : 0
Pointer to Line numbers : 0
Number of relocations : 0
Number of line numbers : 0
Characteristics : Contains initialized data, Readable,
===============================================================================
This Program is written by
K.Vineel Kumar Reddy.
III/IV IT Gayathri Vidya Parishad college of Eng.
C:\work>
2013년 10월 6일 일요일
gdb intel syntax
C:\work>gdb -q memcpy
Reading symbols from C:\work\memcpy.exe...done.
(gdb) set dis intel
Ambiguous set command "dis intel": disable-randomization, disassemble-next-line,
disassembly-flavor, disconnected-tracing...
(gdb) list
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 int main()
5 {
6 char* str1="this is sample string";
7 char* str2;
8
9 str2=(char*)malloc(strlen(str1));
10 memcpy(str2, str1, strlen(str1)+1);(gdb) set disassembly-flavor intel
(gdb) disass main
Dump of assembler code for function main:
0x0040138c <+0>: push ebp
0x0040138d <+1>: mov ebp,esp
0x0040138f <+3>: push edi
0x00401390 <+4>: push esi
0x00401391 <+5>: push ebx
0x00401392 <+6>: and esp,0xfffffff0
0x00401395 <+9>: sub esp,0x30
0x00401398 <+12>: call 0x401944 <__main>
0x0040139d <+17>: mov DWORD PTR [esp+0x2c],0x403064
0x004013a5 <+25>: mov eax,DWORD PTR [esp+0x2c]
0x004013a9 <+29>: mov DWORD PTR [esp+0x1c],0xffffffff
0x004013b1 <+37>: mov edx,eax
0x004013b3 <+39>: mov al,0x0
0x004013b5 <+41>: mov ecx,DWORD PTR [esp+0x1c]
0x004013b9 <+45>: mov edi,edx
0x004013bb <+47>: repnz scas al,BYTE PTR es:[edi]
0x004013bd <+49>: mov eax,ecx
0x004013bf <+51>: not eax
0x004013c1 <+53>: dec eax
0x004013c2 <+54>: mov DWORD PTR [esp],eax
0x004013c5 <+57>: call 0x401b7c <malloc>
0x004013ca <+62>: mov DWORD PTR [esp+0x28],eax
0x004013ce <+66>: mov eax,DWORD PTR [esp+0x2c]
0x004013d2 <+70>: mov DWORD PTR [esp+0x1c],0xffffffff
0x004013da <+78>: mov edx,eax
0x004013dc <+80>: mov al,0x0
0x004013de <+82>: mov ecx,DWORD PTR [esp+0x1c]
0x004013e2 <+86>: mov edi,edx
0x004013e4 <+88>: repnz scas al,BYTE PTR es:[edi]
0x004013e6 <+90>: mov eax,ecx
0x004013e8 <+92>: not eax
0x004013ea <+94>: dec eax
0x004013eb <+95>: inc eax
0x004013ec <+96>: mov edx,DWORD PTR [esp+0x28]
0x004013f0 <+100>: mov ecx,DWORD PTR [esp+0x2c]
0x004013f4 <+104>: mov ebx,ecx
0x004013f6 <+106>: mov edi,edx
0x004013f8 <+108>: mov esi,ebx
0x004013fa <+110>: mov ecx,eax
0x004013fc <+112>: rep movs BYTE PTR es:[edi],BYTE PTR ds:[esi]
0x004013fe <+114>: mov eax,DWORD PTR [esp+0x28]
0x00401402 <+118>: mov DWORD PTR [esp+0x8],eax
0x00401406 <+122>: mov eax,DWORD PTR [esp+0x2c]
0x0040140a <+126>: mov DWORD PTR [esp+0x4],eax
0x0040140e <+130>: mov DWORD PTR [esp],0x40307a
0x00401415 <+137>: call 0x401b84 <printf>
0x0040141a <+142>: mov eax,0x0
0x0040141f <+147>: lea esp,[ebp-0xc]
0x00401422 <+150>: pop ebx
0x00401423 <+151>: pop esi
0x00401424 <+152>: pop edi
0x00401425 <+153>: pop ebp
0x00401426 <+154>: ret
End of assembler dump.
(gdb)
Reading symbols from C:\work\memcpy.exe...done.
(gdb) set dis intel
Ambiguous set command "dis intel": disable-randomization, disassemble-next-line,
disassembly-flavor, disconnected-tracing...
(gdb) list
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 int main()
5 {
6 char* str1="this is sample string";
7 char* str2;
8
9 str2=(char*)malloc(strlen(str1));
10 memcpy(str2, str1, strlen(str1)+1);(gdb) set disassembly-flavor intel
(gdb) disass main
Dump of assembler code for function main:
0x0040138c <+0>: push ebp
0x0040138d <+1>: mov ebp,esp
0x0040138f <+3>: push edi
0x00401390 <+4>: push esi
0x00401391 <+5>: push ebx
0x00401392 <+6>: and esp,0xfffffff0
0x00401395 <+9>: sub esp,0x30
0x00401398 <+12>: call 0x401944 <__main>
0x0040139d <+17>: mov DWORD PTR [esp+0x2c],0x403064
0x004013a5 <+25>: mov eax,DWORD PTR [esp+0x2c]
0x004013a9 <+29>: mov DWORD PTR [esp+0x1c],0xffffffff
0x004013b1 <+37>: mov edx,eax
0x004013b3 <+39>: mov al,0x0
0x004013b5 <+41>: mov ecx,DWORD PTR [esp+0x1c]
0x004013b9 <+45>: mov edi,edx
0x004013bb <+47>: repnz scas al,BYTE PTR es:[edi]
0x004013bd <+49>: mov eax,ecx
0x004013bf <+51>: not eax
0x004013c1 <+53>: dec eax
0x004013c2 <+54>: mov DWORD PTR [esp],eax
0x004013c5 <+57>: call 0x401b7c <malloc>
0x004013ca <+62>: mov DWORD PTR [esp+0x28],eax
0x004013ce <+66>: mov eax,DWORD PTR [esp+0x2c]
0x004013d2 <+70>: mov DWORD PTR [esp+0x1c],0xffffffff
0x004013da <+78>: mov edx,eax
0x004013dc <+80>: mov al,0x0
0x004013de <+82>: mov ecx,DWORD PTR [esp+0x1c]
0x004013e2 <+86>: mov edi,edx
0x004013e4 <+88>: repnz scas al,BYTE PTR es:[edi]
0x004013e6 <+90>: mov eax,ecx
0x004013e8 <+92>: not eax
0x004013ea <+94>: dec eax
0x004013eb <+95>: inc eax
0x004013ec <+96>: mov edx,DWORD PTR [esp+0x28]
0x004013f0 <+100>: mov ecx,DWORD PTR [esp+0x2c]
0x004013f4 <+104>: mov ebx,ecx
0x004013f6 <+106>: mov edi,edx
0x004013f8 <+108>: mov esi,ebx
0x004013fa <+110>: mov ecx,eax
0x004013fc <+112>: rep movs BYTE PTR es:[edi],BYTE PTR ds:[esi]
0x004013fe <+114>: mov eax,DWORD PTR [esp+0x28]
0x00401402 <+118>: mov DWORD PTR [esp+0x8],eax
0x00401406 <+122>: mov eax,DWORD PTR [esp+0x2c]
0x0040140a <+126>: mov DWORD PTR [esp+0x4],eax
0x0040140e <+130>: mov DWORD PTR [esp],0x40307a
0x00401415 <+137>: call 0x401b84 <printf>
0x0040141a <+142>: mov eax,0x0
0x0040141f <+147>: lea esp,[ebp-0xc]
0x00401422 <+150>: pop ebx
0x00401423 <+151>: pop esi
0x00401424 <+152>: pop edi
0x00401425 <+153>: pop ebp
0x00401426 <+154>: ret
End of assembler dump.
(gdb)
2013년 10월 1일 화요일
createprocessnotify
http://blogs.technet.com/b/mmpc/archive/2011/08/10/msrt-august-11-fakesysdef.aspx
call function without importing kernerl32.dll
nasm -f win32 thunked.asm
link /subsystem:console thunked.obj -entry:WinMain
-----
; ------------------------------------------------
; call.asm - finds kernel32.dll in memory and
; searches it's export table for LoadLibraryA()
; and GetProcAddress(). From there, calling
; functions that haven't been imported is trivial.
;
; :-)
;
; Assembled with:
; nasm call.asm -fwin32 -o call.obj
; gcc call.obj -o call.exe
;
; AdhesiveBall - August/2010
; ------------------------------------------------
[BITS 32]
global _WinMain@16
section .data
WorkedMessage db "Hello from an unimported function!", 0
LoadLibraryName db "LoadLibraryA", 0
LoadLibraryAddr dd 0xFFFFFFFF
GetProcAddressName db "GetProcAddress", 0
GetProcAddressAddr dd 0xFFFFFFFF
MessageBoxName db "MessageBoxA", 0
MessageBoxAddr dd 0xFFFFFFFF
User32Name db "user32.dll", 0
User32Addr db 0xFFFFFFFF
Kernel32Addr dd 0xFFFFFFFF
section .text
; -----------------------------------------------
; void *FindKernel32Base(void)
; tries to find the base address of kernel32.dll
; returns NULL on error
; -----------------------------------------------
FindKernel32Base:
mov eax, [fs:0x30] ; address of PEB
mov eax, [eax + 0x0C] ; PEB->Ldr
mov eax, [eax + 0x1C] ; Ldr->InMemoryOrderModuleList (first element is ntdll.dll)
mov eax, [eax] ; InMemoryOrderModuleList->Flink (second element is kernel32.dll)
mov eax, [eax + 0x08] ; DllBase
cmp word [eax], 'MZ' ; check for MZ header
je FindKernel32Base_end
xor eax, eax ; zero eax if not found
FindKernel32Base_end:
ret
; ------------------------------------------------------
; void *LoadFunction(HMODULE module, char *FunctionName)
; attempts to find the address of function by
; walking module's Export Address Table
; ------------------------------------------------------
LoadK32Function:
push ebp
mov ebp, esp
sub esp, 12 ; make room for 3 DWORDS
; look at my stack frame, my stack frame's amazing
;------------------------------------
; +-----------------------+
; ebp-0x0C | PE Header |
; +-----------------------+
; ebp-0x08 | Export table addr |
; +-----------------------+
; ebp-0x04 | AddressOfNames |
; +-----------------------+
; .....
; +-----------------------+
; ebp+0x08 | kernel32 base address |
; +-----------------------+
; ebp+0x0C | function name |
; +-----------------------+
;------------------------------------
mov edi, [ebp + 0x08] ; edi = DosHeader
; -------------------------
; verify MZ and PE headers
; -------------------------
cmp word [edi], 'MZ'
jne LoadK32Function_fail
mov edx, edi
add edx, [edi + 0x3C] ; module + DosHeader->e_lfanew (edx = PeHeader)
cmp word [edx], 'PE'
jne LoadK32Function_fail
mov [ebp - 0x0C], edx ; save the PE header
; ------------------------------
; find the real addr of the EAT
; ------------------------------
mov eax, [edx + 0x78] ; OptionalHeader.DataDirectory[0].VirtualAddress
add eax, dword [ebp + 0x08] ; add the offset to the base address
mov [ebp - 0x08], eax ; save it!
; ----------------------------------------
; find the real address of export names
; ----------------------------------------
mov eax, [eax + 0x20] ; eax is still addr of EAT (0x20 = offset to ADdressOfNames)
add eax, dword [ebp + 0x08]
mov [ebp - 0x04], eax
; --------------------------------
; start looking for names!
; --------------------------------
xor ecx, ecx
LoadK32Function_loop_names:
mov edx, [ebp - 0x08] ; EAT
cmp ecx, [edx + 0x18] ; NumberOfNames
jge LoadK32Function_fail
; --------------------------------------
; find the address of the function name
; --------------------------------------
mov ebx, [ebp - 0x04] ; AddressOfNames
mov ebx, [ebx + ecx * 4] ; RVA of string
add ebx, [ebp + 0x08]
; compare 'em!
push dword [ebp + 0x0C] ; FunctionName
push ebx ; name of entry
call strcmp
cmp eax, 1
je LoadK32Function_found_api
inc ecx
jmp LoadK32Function_loop_names
LoadK32Function_found_api:
;------------------------------------------------------
; success! now all that's left is to go from the
; AddressOfNames index to the AddressOfFunctions index
; -----------------------------------------------------
; First thing's first, find the AddressOfNameOrdinals address
mov eax, [ebp - 0x08]
mov eax, [eax + 0x24] ; AddressOfNameOrdinals offset
add eax, [ebp + 0x08]
; Now we gotta look up the ordinal corresponding to our api
xor ebx, ebx
mov bx, [eax + ecx * 2] ; ecx * 2 because it's an array of WORDS
; Next we find the AddressOfFunctions array
mov eax, [ebp - 0x08]
mov eax, [eax + 0x1C] ; AddressOfFunctions offset
add eax, [ebp + 0x08]
; and last we find the address of our api!
mov eax, [eax + ebx * 4]
add eax, [ebp + 0x08]
jmp LoadK32Function_end
LoadK32Function_fail:
xor eax, eax
LoadK32Function_end:
mov esp, ebp
pop ebp
ret 8
; -------------------------------------------------------------
; unsigned int RVAToFileOffset(
; IMAGE_NT_HEADERS *ntHeader, unsigned long virtualAddr);
;
; Converts a relative virtual address to an offset in the file
; -------------------------------------------------------------
;RvaToFileOffset:
; push ebx
; mov eax, [esp + 0x08] ; eax = ntHeader
; mov ebx, [esp + 0x0C] ; ebx = virtualAddr
; push ecx
; push edx
; xor ecx, ecx
; mov cx, [eax + 0x06] ; ecx = number of sections
; lea edx, [eax + 0xF8] ; edx = first section
; RvaToFileOffset_loop_sections:
; push ecx ; used as a temporary variable throughout the loop
;
; ; -------------------------------------------------------------
; ; check if the virtual address resides in the current function
; ; -------------------------------------------------------------
; cmp ebx, [edx + 0x0C] ; if(virtualAddr < section->VirtualAddress) continue;
; jl RvaToFileOffset_continue
; mov ecx, [edx + 0x0C]
; add ecx, [edx + 0x08] ; ecx = section->VirtualAddress + section->VirtualSize
; cmp ebx, ecx ; if(virtualAddr >= ecx) continue;
; jge RvaToFileOffset_continue
;
; RvaToFileOffset_DEBUGLABEL:
; ; -------------------
; ; Success! It's here
; ; -------------------
; sub ebx, [edx + 0x0C] ; find the offset from the beginning of the section's virtual addr
; add ebx, [edx + 0x14] ; add it to the PointerToRawData member
; jmp RvaToFileOffset_success
;
;; RvaToFileOffset_continue:
; add edx, 0x28 ; edx += sizeof(IMAGE_SECTION_HEADER)
; pop ecx ; restore for use as a counter
; loop RvaToFileOffset_loop_sections
;
; xor eax, eax ; baww
; jmp RvaToFileOffset_end
;
;RvaToFileOffset_success:
; pop ecx ; ecx will be on the stack 'coz of the loop so we need to fix it
; mov eax, ebx
;RvaToFileOffset_end:
; pop edx
; pop ecx
; pop ebx
; ret 8
; -------------------------------------------------
; int strcmp(char *a, char *b)
; returns 1 if the two strings are equal, 0 if not
; -------------------------------------------------
strcmp:
push ebx
strcmp_loop:
mov eax, [esp + 0x08]
mov al, byte [eax]
mov ebx, [esp + 0x0C]
cmp al, byte [ebx]
jne strcmp_not_equal
cmp al, 0
je strcmp_equal
inc dword [esp + 0x0C]
inc dword [esp + 0x08]
jmp strcmp_loop
strcmp_not_equal:
mov eax, 0
jmp strcmp_end
strcmp_equal:
mov eax, 1
strcmp_end:
pop ebx
ret 8
; -----------------------------------------------
; kinda bloated but meh does it's job
_WinMain@16:
call FindKernel32Base
cmp eax, 0
je _WinMain_failed
mov [Kernel32Addr], eax
; find LoadLibrary()
push LoadLibraryName
push dword [Kernel32Addr]
call LoadK32Function
cmp eax, 0
je _WinMain_failed
mov [LoadLibraryAddr], eax
; find GetProcAddress()
push GetProcAddressName
push dword [Kernel32Addr]
call LoadK32Function
cmp eax, 0
je _WinMain_failed
mov [GetProcAddressAddr], eax
; load user32.dll
push User32Name
call [LoadLibraryAddr]
cmp eax, 0
je _WinMain_failed
mov [User32Addr], eax
; find MessageBox()
push MessageBoxName
push dword [User32Addr]
call [GetProcAddressAddr]
cmp eax, 0
je _WinMain_failed
mov [MessageBoxAddr], eax
push 0
push WorkedMessage
push WorkedMessage
push 0
call [MessageBoxAddr]
_WinMain_worked:
; push 0
; push WorkedMessage
; push WorkedMessage
; push 0
; call _MessageBoxA@16
; jmp _WinMain_end
_WinMain_failed:
; push 0
; push FailedMessage
; push FailedMessage
; push 0
; call _MessageBoxA@16
_WinMain_end:
ret 16
link /subsystem:console thunked.obj -entry:WinMain
-----
; ------------------------------------------------
; call.asm - finds kernel32.dll in memory and
; searches it's export table for LoadLibraryA()
; and GetProcAddress(). From there, calling
; functions that haven't been imported is trivial.
;
; :-)
;
; Assembled with:
; nasm call.asm -fwin32 -o call.obj
; gcc call.obj -o call.exe
;
; AdhesiveBall - August/2010
; ------------------------------------------------
[BITS 32]
global _WinMain@16
section .data
WorkedMessage db "Hello from an unimported function!", 0
LoadLibraryName db "LoadLibraryA", 0
LoadLibraryAddr dd 0xFFFFFFFF
GetProcAddressName db "GetProcAddress", 0
GetProcAddressAddr dd 0xFFFFFFFF
MessageBoxName db "MessageBoxA", 0
MessageBoxAddr dd 0xFFFFFFFF
User32Name db "user32.dll", 0
User32Addr db 0xFFFFFFFF
Kernel32Addr dd 0xFFFFFFFF
section .text
; -----------------------------------------------
; void *FindKernel32Base(void)
; tries to find the base address of kernel32.dll
; returns NULL on error
; -----------------------------------------------
FindKernel32Base:
mov eax, [fs:0x30] ; address of PEB
mov eax, [eax + 0x0C] ; PEB->Ldr
mov eax, [eax + 0x1C] ; Ldr->InMemoryOrderModuleList (first element is ntdll.dll)
mov eax, [eax] ; InMemoryOrderModuleList->Flink (second element is kernel32.dll)
mov eax, [eax + 0x08] ; DllBase
cmp word [eax], 'MZ' ; check for MZ header
je FindKernel32Base_end
xor eax, eax ; zero eax if not found
FindKernel32Base_end:
ret
; ------------------------------------------------------
; void *LoadFunction(HMODULE module, char *FunctionName)
; attempts to find the address of function by
; walking module's Export Address Table
; ------------------------------------------------------
LoadK32Function:
push ebp
mov ebp, esp
sub esp, 12 ; make room for 3 DWORDS
; look at my stack frame, my stack frame's amazing
;------------------------------------
; +-----------------------+
; ebp-0x0C | PE Header |
; +-----------------------+
; ebp-0x08 | Export table addr |
; +-----------------------+
; ebp-0x04 | AddressOfNames |
; +-----------------------+
; .....
; +-----------------------+
; ebp+0x08 | kernel32 base address |
; +-----------------------+
; ebp+0x0C | function name |
; +-----------------------+
;------------------------------------
mov edi, [ebp + 0x08] ; edi = DosHeader
; -------------------------
; verify MZ and PE headers
; -------------------------
cmp word [edi], 'MZ'
jne LoadK32Function_fail
mov edx, edi
add edx, [edi + 0x3C] ; module + DosHeader->e_lfanew (edx = PeHeader)
cmp word [edx], 'PE'
jne LoadK32Function_fail
mov [ebp - 0x0C], edx ; save the PE header
; ------------------------------
; find the real addr of the EAT
; ------------------------------
mov eax, [edx + 0x78] ; OptionalHeader.DataDirectory[0].VirtualAddress
add eax, dword [ebp + 0x08] ; add the offset to the base address
mov [ebp - 0x08], eax ; save it!
; ----------------------------------------
; find the real address of export names
; ----------------------------------------
mov eax, [eax + 0x20] ; eax is still addr of EAT (0x20 = offset to ADdressOfNames)
add eax, dword [ebp + 0x08]
mov [ebp - 0x04], eax
; --------------------------------
; start looking for names!
; --------------------------------
xor ecx, ecx
LoadK32Function_loop_names:
mov edx, [ebp - 0x08] ; EAT
cmp ecx, [edx + 0x18] ; NumberOfNames
jge LoadK32Function_fail
; --------------------------------------
; find the address of the function name
; --------------------------------------
mov ebx, [ebp - 0x04] ; AddressOfNames
mov ebx, [ebx + ecx * 4] ; RVA of string
add ebx, [ebp + 0x08]
; compare 'em!
push dword [ebp + 0x0C] ; FunctionName
push ebx ; name of entry
call strcmp
cmp eax, 1
je LoadK32Function_found_api
inc ecx
jmp LoadK32Function_loop_names
LoadK32Function_found_api:
;------------------------------------------------------
; success! now all that's left is to go from the
; AddressOfNames index to the AddressOfFunctions index
; -----------------------------------------------------
; First thing's first, find the AddressOfNameOrdinals address
mov eax, [ebp - 0x08]
mov eax, [eax + 0x24] ; AddressOfNameOrdinals offset
add eax, [ebp + 0x08]
; Now we gotta look up the ordinal corresponding to our api
xor ebx, ebx
mov bx, [eax + ecx * 2] ; ecx * 2 because it's an array of WORDS
; Next we find the AddressOfFunctions array
mov eax, [ebp - 0x08]
mov eax, [eax + 0x1C] ; AddressOfFunctions offset
add eax, [ebp + 0x08]
; and last we find the address of our api!
mov eax, [eax + ebx * 4]
add eax, [ebp + 0x08]
jmp LoadK32Function_end
LoadK32Function_fail:
xor eax, eax
LoadK32Function_end:
mov esp, ebp
pop ebp
ret 8
; -------------------------------------------------------------
; unsigned int RVAToFileOffset(
; IMAGE_NT_HEADERS *ntHeader, unsigned long virtualAddr);
;
; Converts a relative virtual address to an offset in the file
; -------------------------------------------------------------
;RvaToFileOffset:
; push ebx
; mov eax, [esp + 0x08] ; eax = ntHeader
; mov ebx, [esp + 0x0C] ; ebx = virtualAddr
; push ecx
; push edx
; xor ecx, ecx
; mov cx, [eax + 0x06] ; ecx = number of sections
; lea edx, [eax + 0xF8] ; edx = first section
; RvaToFileOffset_loop_sections:
; push ecx ; used as a temporary variable throughout the loop
;
; ; -------------------------------------------------------------
; ; check if the virtual address resides in the current function
; ; -------------------------------------------------------------
; cmp ebx, [edx + 0x0C] ; if(virtualAddr < section->VirtualAddress) continue;
; jl RvaToFileOffset_continue
; mov ecx, [edx + 0x0C]
; add ecx, [edx + 0x08] ; ecx = section->VirtualAddress + section->VirtualSize
; cmp ebx, ecx ; if(virtualAddr >= ecx) continue;
; jge RvaToFileOffset_continue
;
; RvaToFileOffset_DEBUGLABEL:
; ; -------------------
; ; Success! It's here
; ; -------------------
; sub ebx, [edx + 0x0C] ; find the offset from the beginning of the section's virtual addr
; add ebx, [edx + 0x14] ; add it to the PointerToRawData member
; jmp RvaToFileOffset_success
;
;; RvaToFileOffset_continue:
; add edx, 0x28 ; edx += sizeof(IMAGE_SECTION_HEADER)
; pop ecx ; restore for use as a counter
; loop RvaToFileOffset_loop_sections
;
; xor eax, eax ; baww
; jmp RvaToFileOffset_end
;
;RvaToFileOffset_success:
; pop ecx ; ecx will be on the stack 'coz of the loop so we need to fix it
; mov eax, ebx
;RvaToFileOffset_end:
; pop edx
; pop ecx
; pop ebx
; ret 8
; -------------------------------------------------
; int strcmp(char *a, char *b)
; returns 1 if the two strings are equal, 0 if not
; -------------------------------------------------
strcmp:
push ebx
strcmp_loop:
mov eax, [esp + 0x08]
mov al, byte [eax]
mov ebx, [esp + 0x0C]
cmp al, byte [ebx]
jne strcmp_not_equal
cmp al, 0
je strcmp_equal
inc dword [esp + 0x0C]
inc dword [esp + 0x08]
jmp strcmp_loop
strcmp_not_equal:
mov eax, 0
jmp strcmp_end
strcmp_equal:
mov eax, 1
strcmp_end:
pop ebx
ret 8
; -----------------------------------------------
; kinda bloated but meh does it's job
_WinMain@16:
call FindKernel32Base
cmp eax, 0
je _WinMain_failed
mov [Kernel32Addr], eax
; find LoadLibrary()
push LoadLibraryName
push dword [Kernel32Addr]
call LoadK32Function
cmp eax, 0
je _WinMain_failed
mov [LoadLibraryAddr], eax
; find GetProcAddress()
push GetProcAddressName
push dword [Kernel32Addr]
call LoadK32Function
cmp eax, 0
je _WinMain_failed
mov [GetProcAddressAddr], eax
; load user32.dll
push User32Name
call [LoadLibraryAddr]
cmp eax, 0
je _WinMain_failed
mov [User32Addr], eax
; find MessageBox()
push MessageBoxName
push dword [User32Addr]
call [GetProcAddressAddr]
cmp eax, 0
je _WinMain_failed
mov [MessageBoxAddr], eax
push 0
push WorkedMessage
push WorkedMessage
push 0
call [MessageBoxAddr]
_WinMain_worked:
; push 0
; push WorkedMessage
; push WorkedMessage
; push 0
; call _MessageBoxA@16
; jmp _WinMain_end
_WinMain_failed:
; push 0
; push FailedMessage
; push FailedMessage
; push 0
; call _MessageBoxA@16
_WinMain_end:
ret 16
피드 구독하기:
글 (Atom)