shellcode就是汇编的opcode,一般以子函数形式出现:
取得shellcode的方便方式是:
1.写一个函数如:
void __stdcall code(LONG &a, LONG &b, DWORD &c, LONG &d, DWORD &e)取得它的汇编码:如:
push ebp mov ebp,esp sub esp,14h push ebx push esi push edi mov dword ptr [ebp-4],0FFFFFFFFh mov dword ptr [ebp-0Ch],0 mov dword ptr [ebp-8],0 mov dword ptr [ebp-14h],0 mov dword ptr [ebp-10h],0 pushad mov eax,22E4CCh int 0FFh mov dword ptr [ebp-4],eax mov dword ptr [ebp-0Ch],ecx mov dword ptr [ebp-14h],edx mov dword ptr [ebp-8],esi mov dword ptr [ebp-10h],edi popad mov eax,dword ptr [ebp+8] mov ecx,dword ptr [ebp-4] mov dword ptr [eax],ecx mov edx,dword ptr [ebp+0Ch] mov eax,dword ptr [ebp-0Ch] mov dword ptr [edx],eax mov ecx,dword ptr [ebp+10h] mov edx,dword ptr [ebp-14h] mov dword ptr [ecx],edx mov eax,dword ptr [ebp+14h] mov ecx,dword ptr [ebp-8] mov dword ptr [eax],ecx mov edx,dword ptr [ebp+18h] mov eax,dword ptr [ebp-10h] mov dword ptr [edx],eax pop edi pop esi pop ebx mov esp,ebp pop ebp ret 14h转换成机器码:
unsigned char *asm_code() { __asm { lea eax,__code jmp __ret } // shellcode __asm { __code://要加的汇编 //TODO } __asm nop//标志位,一般是int 3,即0xcc __asm {__ret:} }
int main() { unsigned char temp; int i=1; unsigned char* asm_p = asm_code(); FILE *fd = fopen("code.txt","w"); fprintf(fd,"unsigned char shellcode[] = ""); while((temp = *asm_p) != 0x90)//标志位,一般是int 3,即0xcc { fprintf(fd,"\x%.2x",temp); asm_p ++; if(i % 8 == 0) fprintf(fd,"" ""); i ++; } fprintf(fd,"";"); fclose(fd);运行得到shellcode[]数组在code.txt中,取出
调用方式一般采用:
#define QSHELLCODE {0x55, 0x8b, 0xec, 0xcd, 0xff, 0x5d, 0xc3} #define SHELLCODE_SIZE 0x7
PVOID m_pShellCode = VirtualAlloc(NULL, SHELLCODE_SIZE, MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE); if (m_pShellCode) { byte ptr_shellcode[] = QSHELLCODE; memcpy(m_pShellCode, ptr_shellcode,SHELLCODE_SIZE); }最后调用有两种方式,一种是:
pfn_Q pfn = (pfn_Q)m_ShellCode; pfn(填参数);//函数直接调另一种是汇编:
lea ecx, pfn mov ecx, [ecx] call ecx当然,有参数就先push参数