32位汇编第三讲----【RedASM与代码注入】(2016-12-16)

来源:互联网 发布:iota 网络被攻击 编辑:程序博客网 时间:2024/06/06 03:03

0x00 关于函数入口点的指定

#pragma comment( linker, "/subsystem:windows /entry:WinMainCRTStartup" )#pragma comment( linker, "/subsystem:windows /entry:mainCRTStartup" )#pragma comment( linker, "/subsystem:console /entry:mainCRTStartup" )#pragma comment( linker, "/subsystem:console /entry:WinMainCRTStartup" )int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR      lpCmdLine,int        nCmdShow){      // ...}int main(void){      // ...}
  • mainCRTStartup的作用

作用:

它在执行一些初始化操作,如获取命令行参数、获取环境变量值、初始化全局变量、初始化io的所需各项准备之后,调用main(argc,argv)。main函数返回后,mainCRTStartup还需要调用全局变量的析构函数或者atexit()所登记的一些函数

0x02 代码注入与重定位

  • 为什么要先进行重定位

对于注入的代码,注入的地址与原本的地址不同

  • 如何重定位

当CALL执行时,CPU首先把要返回的地址
(即下一条指令的地址)压入堆栈,然后跳到我们目的地址执行。可以看出,在跳转之后只要执行一条POP指令或MOV
EXX,[ESP]就可以得到下一条指令在内存中的实际位置了。其实,对于任何一个变量,我们都可以采用这种方式进行重定位

基本步骤如下:

(1)用CALL指令跳转到下一条指令,使z1在内存中的实际地址进栈。 (2)用POP xx 或MOV
EXX,[ESP]取出栈顶的内容,这样就得到了z1的地址 (BaSe)。 (3)其他指令
(变量、常量)的实际地址就等于Base+(0ffSetLabe1-OffSet vstart)。

实例代码:

//----------------------------    call vStart  // call这个动作发生的时候,会把返回地址退入堆栈的顶部,此时返回地址就是vStart所在位置的绝对地址,当然call这个函数是通过相对偏移来调用的,不存在重定位的问题vStart:    pop ebp  //这里取出返回地址,注意此地址是进程空间里面的绝对地址    sub ebp,offset vStart //把绝对地址和相对偏移相减就可以获得相对偏移与绝对地址的转换关系    mov eax, [ebp+kernel32]  ;//有了转换关系之后就可以轻松调用各个由相对地址指定的数据段或者函数    kernel32        dd     ?//-------------------------------

代码注入的32位汇编关键代码:

begin_label:     call $+5  ;重定位FIXADDR:    pop ebp    sub ebp, FIXADDR    push MB_OK    lea eax, [ebp + offset g_szTitle]    push eax    lea eax, [ebp + offset g_szMsg]    push eax    push NULL    mov eax, [ebp + offset g_pfnMessageBox]    call eax    ret    g_szTitle db 'Title', 0    g_szMsg db 'Hello World', 0    g_pfnMessageBox DWORD 0end_label:InjectCode proc    LOCAL @hCalc:HWND    LOCAL @dwPid :dword    LOCAL @hProcess :HANDLE    LOCAL @lpBuff :PVOID    LOCAL @hUser:HANDLE    LOCAL @oldProtect:DWORD    LOCAL @lpMsgBox:PVOID    invoke LoadLibrary, addr g_szUser32    mov @hUser, eax    ;check    .if eax == NULL        invoke MessageBox,NULL,offset g_szUser32,offset g_err,MB_OK        ret    .endif    invoke GetProcAddress, @hUser, addr g_szMsgBox    mov @lpMsgBox, eax    ;check    .if eax == NULL        invoke MessageBox,NULL,offset g_szGetProcAddress,offset g_err,MB_OK        ret    .endif    ;修改内存保护属性    invoke VirtualProtect, addr begin_label,  end_label -  begin_label, \            PAGE_EXECUTE_READWRITE, addr @oldProtect    ;check    .if eax == NULL        invoke MessageBox,NULL,offset g_szVirtualProtect,offset g_err,MB_OK        ret    .endif    mov eax, @lpMsgBox          mov g_pfnMessageBox, eax    ;修改完一次过后需要再吃修改最开始的状态    invoke VirtualProtect, addr begin_label,  end_label -  begin_label, \            @oldProtect, addr @oldProtect    ;check    .if eax == NULL        invoke MessageBox,NULL,offset g_szVirtualProtect,offset g_err,MB_OK        ret    .endif    invoke FreeLibrary,@hUser    ;check    .if eax == NULL        invoke MessageBox,NULL,offset g_szFreeLibrary,offset g_err,MB_OK        ret    .endif    invoke FindWindow,NULL, addr g_szCalc    mov @hCalc, eax    ;check    .if eax == NULL        invoke MessageBox,NULL,offset g_szFindWindow,offset g_err,MB_OK        ret    .endif    invoke GetWindowThreadProcessId,@hCalc, addr @dwPid    ;check    mov eax,@dwPid    .if eax == NULL        invoke MessageBox,NULL,offset g_szGetWindowThreadProcessId,offset g_err,MB_OK        ret    .endif    invoke OpenProcess, PROCESS_ALL_ACCESS, FALSE, @dwPid    mov @hProcess, eax    ;check    .if eax == NULL        invoke MessageBox,NULL,offset g_szOpenProcess,offset g_err,MB_OK        ret    .endif    ;申请内存    invoke VirtualAllocEx, @hProcess, NULL, 1000h, MEM_COMMIT, PAGE_EXECUTE_READWRITE    mov @lpBuff, eax    mov g_szAddr,eax    ;check    .if eax == NULL        invoke MessageBox,NULL,offset g_szVirtualAllocEx,offset g_err,MB_OK        ret    .endif    ;写入内存    invoke WriteProcessMemory,@hProcess, @lpBuff, \        addr begin_label, end_label - begin_label, NULL    ;check    .if eax == 0        invoke MessageBox,NULL,offset g_szWriteProcessMemory,offset g_err,MB_OK        ret    .endif    ;创建远程线程    invoke CreateRemoteThread,@hProcess, NULL, 0, @lpBuff, NULL, 0, NULL    ;check    .if eax == NULL        invoke MessageBox,NULL,offset g_szCreateRemoteThread,offset g_err,MB_OK        ret    .endif    ;释放内存    invoke VirtualFreeEx,@hProcess, @lpBuff, 1000h, MEM_RELEASE    ;check    .if eax == 0        invoke MessageBox,NULL,offset g_szVirtualFreeEx,offset g_err,MB_OK        ret    .endif    retInjectCode endp
0 0
原创粉丝点击