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)
2013년 10월 6일 일요일
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
2013년 9월 29일 일요일
[nasm\print hello
nasm -f win32 hello.asm
------
C:\work>link hello.obj msvcrt.lib
Microsoft (R) Incremental Linker Version 6.00.8168
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
C:\work>hello
Hello, World
C:\work>
------
C:\work>link hello.obj msvcrt.lib
Microsoft (R) Incremental Linker Version 6.00.8168
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
C:\work>hello
Hello, World
C:\work>
2013년 9월 27일 금요일
entry point
dumpbin /headers \Windows\bfsvc
Dump of file \Windows\bfsvc.exe
PE signature found
File Type: EXECUTABLE IMAGE
FILE HEADER VALUES
14C machine (x86)
4 number of sections
4A5BBFB3 time date stamp Tue Jul 14 01:13:55 2009
0 file pointer to symbol table
0 number of symbols
E0 size of optional header
102 characteristics
Executable
32 bit word machine
OPTIONAL HEADER VALUES
10B magic # (PE32)
9.00 linker version
DE00 size of code
2000 size of initialized data
0 size of uninitialized data
4149 entry point (01004149)
1000 base of code
F000 base of data
1000000 image base (01000000 to 01011FFF)
1000 section alignment
200 file alignment
피드 구독하기:
글 (Atom)
