Win32汇编实现DLL的远程注入及卸载

(声明:魏滔序原创,转贴请注明出处。)
        所谓DLL远程注入,就是强迫DLL程序运行在其他进程中,这样做的目的无非有两种:第一是伪装自身,第二是控制宿主。前者常见于病毒或木马,后者则一般用于正规之场合,比如常见的输入法、外挂等等,有时Hook(钩子)也用到该技术。由此可见,技术是把双刃剑,区别在于使用技术的人。

DLL远程注入的方法一般有如下几种:
1.修改注册表,系统启动时自动加载。当然,如果卸载就要关闭系统了,或者使用本文的卸载功能。
2.使用SetWindowsHookEx进行注入,该参数最后一个参数值决定注入的全局与否。
3.BHO,这个没什么可说的,仅局限与浏览器。
4.使用CreateRemoteThread进行注入,也就是本文的主要内容。

注入过程大致是:
1.打开目标进程。
2.在目标进程中申请一块内存,用来存放要注入的dll名称。
3.将dll名称写入该内存。
4.获得LoadLibraryA函数的地址,该函数在任何进程中的地址都相同。
5.创建远程线程,也就是执行LoadLibraryA函数了。当然LoadLibraryA的参数就是上面保存的dll名称。
6.等待线程返回
        到此为止,dll已经被成功在远程进程中运行了,至于运行后该如何工作,那就发挥你无穷的想像力吧。卸载过程与注入过程雷同,只是区别于后面使用了FreeLibrary函数进行卸载。注意,FreeLibrary函数只能传入模块的句柄,可使用GetModuleHandleA函数获得。

源码奉上:

 ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 ; Win32汇编实现DLL的远程注入及卸载  
 ; Programmed by 魏滔序                  
 ; WebSite: http:
// www.chenoe.com        
 ; Blog: http:
// blog.csdn.net / Modest         
 ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  
    .
486             ;   create    32    bit   code 
    .model    flat,    stdcall    ;   
32    bit   memory   model 
    
option     casemap    :none    ;    case    sensitive 
    
    include    windows.inc 
    include    kernel32.inc 
    includelib kernel32.lib 
    
    RemoteInjectModule    PROTO :DWORD,:DWORD
    RemoteUnloadModule    PROTO :DWORD,:DWORD
.data 
    szKernel32     db 
' Kernel32',0
    szGetModuleHandleA db  ' GetModuleHandleA',0
    szLoadLibraryA    db  ' LoadLibraryA',0
    szFreeLibrary    db  ' FreeLibrary',0
.code 

Start:
    
RemoteInjectModule proc dwProcID,pszModule
    LOCAL    hProcess, hThread, dwExitCode
    LOCAL    pszBuffer,pdwAddress
    
    Invoke    OpenProcess,PROCESS_QUERY_INFORMATION 
Or  PROCESS_CREATE_THREAD  Or  PROCESS_VM_OPERATION  Or  PROCESS_VM_WRITE,  0 , dwProcID
    MOV    hProcess,EAX
    .If     hProcess 
==   0
        JMP ErrHandle
    .Endif
    
    Invoke    VirtualAllocEx,hProcess, 
0 , MAX_PATH, MEM_COMMIT, PAGE_READWRITE
    MOV    pszBuffer,EAX
    .If     pszBuffer 
==   0  
        JMP ErrHandle
    .Endif
    
    Invoke    WriteProcessMemory,hProcess, pszBuffer, pszModule, MAX_PATH, 
0
    .If     EAX 
==   0
        JMP ErrHandle
    .Endif
    
    Invoke    GetModuleHandle,addr szKernel32
    Invoke    GetProcAddress,EAX, addr szLoadLibraryA
    MOV    pdwAddress,EAX
    .If     pdwAddress 
==   0
        JMP ErrHandle
    .Endif
    
    Invoke    CreateRemoteThread,hProcess, 
0 , 0 , pdwAddress, pszBuffer,  0 0
    MOV    hThread,EAX
    .If     hThread 
==   0
        JMP ErrHandle
    .Endif
    
    Invoke    WaitForSingleObject,hThread, INFINITE
    Invoke    GetExitCodeThread,hThread,addr dwExitCode
    .If     dwExitCode !
=   0
        Invoke    VirtualFreeEx, hProcess, pszBuffer, 
0 , MEM_RELEASE
        Invoke    CloseHandle,hProcess
        MOV    EAX,
1
    .else
        MOV    EAX,
0
    .endif
    
    RET
    
ErrHandle:
    .If     pszBuffer !
=   0
        Invoke    VirtualFreeEx, hProcess, pszBuffer, 
0 , MEM_RELEASE
    .Endif
    
    .If     hThread !
=   0
        Invoke    CloseHandle, hThread
    .Endif
    
    .If     hProcess !
=   0
        Invoke    CloseHandle,hProcess
    .Endif
    
    MOV    EAX,
0
    RET
RemoteInjectModule endp 
    
RemoteUnloadModule proc dwProcID,pszModule
    LOCAL    hProcess, hThread, dwExitCode
    LOCAL    pszBuffer,pdwAddress
    
    Invoke    OpenProcess,PROCESS_QUERY_INFORMATION 
Or  PROCESS_CREATE_THREAD  Or  PROCESS_VM_OPERATION  Or  PROCESS_VM_WRITE,  0 , dwProcID
    MOV    hProcess,EAX
    .If     hProcess 
==   0
        JMP ErrHandle
    .Endif
    
    Invoke    VirtualAllocEx,hProcess, 
0 , MAX_PATH, MEM_COMMIT, PAGE_READWRITE
    MOV    pszBuffer,EAX
    .If     pszBuffer 
==   0
        JMP ErrHandle
    .Endif
    
    Invoke    WriteProcessMemory,hProcess, pszBuffer, pszModule, MAX_PATH, 
0
    .If     EAX
== 0
        JMP ErrHandle
    .Endif
    
    Invoke    GetModuleHandle,addr szKernel32
    Invoke    GetProcAddress,EAX, addr szGetModuleHandleA
    MOV    pdwAddress,EAX
    .If     pdwAddress 
==   0
        JMP ErrHandle
    .Endif
    
    Invoke    CreateRemoteThread,hProcess, 
0 0 , pdwAddress, pszBuffer,  0 , 0
    MOV    hThread,EAX
    .If     hThread 
==   0
        JMP ErrHandle
    .Endif
    
    Invoke    WaitForSingleObject,hThread, INFINITE
    Invoke    GetExitCodeThread, hThread, addr dwExitCode
    

    
    Invoke    VirtualFreeEx, hProcess, pszBuffer, 
0 , MEM_RELEASE
    Invoke    CloseHandle, hThread
    
    Invoke    GetModuleHandle,addr szKernel32
    Invoke    GetProcAddress,EAX, addr szFreeLibrary
    MOV    pdwAddress,EAX
    .If     pdwAddress 
==   0
        JMP ErrHandle
    .Endif
    
    Invoke    CreateRemoteThread,hProcess, 
0 0 , pdwAddress, dwExitCode,  0 , 0
    MOV    hThread,EAX
    .If     hThread 
==   0
        JMP ErrHandle
    .Endif
    
    Invoke    WaitForSingleObject,hThread, INFINITE
    Invoke    GetExitCodeThread, hThread, addr dwExitCode
    .If     dwExitCode !
=   0
        Invoke    VirtualFreeEx, hProcess, pszBuffer, 
0 , MEM_RELEASE
        Invoke    CloseHandle,hProcess
        MOV    EAX,
1
    .else
        MOV    EAX,
0
    .endif
    
    RET
    
ErrHandle:
    .If     pszBuffer !
=   0
        Invoke    VirtualFreeEx, hProcess, pszBuffer, 
0 , MEM_RELEASE
    .Endif
    
    .If     hThread !
=   0
        Invoke    CloseHandle, hThread
    .Endif
    
    .If     hProcess !
=   0
        Invoke    CloseHandle,hProcess
    .Endif
    
    MOV    EAX,
0
    RET
RemoteUnloadModule endp

End    Start
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
下面是一个Win32汇编秒表程序,使用了Windows API中的计时器函数来实现毫秒级的计时和显示: ``` .386 .model flat, stdcall option casemap:none include \masm32\include\windows.inc include \masm32\include\user32.inc includelib \masm32\lib\user32.lib include \masm32\include\kernel32.inc includelib \masm32\lib\kernel32.lib .data msg db 'Time:',13,10,0 count dd 0 tick dd 0 hWnd dd 0 .code start: ; 创建窗口 invoke GetModuleHandle, NULL mov hInstance, eax invoke WinMain, hInstance, NULL, NULL, SW_SHOWDEFAULT invoke ExitProcess, eax WinMain proc hInst:HINSTANCE, hPrevInst:HINSTANCE, lpCmdLine:LPSTR, nCmdShow:DWORD mov eax, hInst mov hInstance, eax ; 注册窗口类 mov wc.cbSize, SIZEOF WNDCLASSEX mov wc.style, CS_HREDRAW or CS_VREDRAW mov wc.lpfnWndProc, offset WndProc mov wc.cbClsExtra, 0 mov wc.cbWndExtra, 0 push hInstance pop wc.hInstance mov wc.hbrBackground, COLOR_WINDOW+1 mov wc.lpszMenuName, NULL mov wc.lpszClassName, offset szClassName push IDI_APPLICATION push NULL call LoadIcon mov wc.hIcon, eax mov wc.hIconSm, eax push IDI_APPLICATION push NULL call LoadCursor mov wc.hCursor, eax invoke RegisterClassEx, addr wc ; 创建窗口 invoke CreateWindowEx, WS_EX_CLIENTEDGE, offset szClassName, offset szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 320, 240, NULL, NULL, hInstance, NULL mov hWnd, eax invoke ShowWindow, hWnd, SW_SHOW invoke UpdateWindow, hWnd ; 设置计时器 invoke SetTimer, hWnd, 1, 1, NULL ; 消息循环 msgloop: invoke GetMessage, ADDR msg, NULL, 0, 0 cmp eax, 0 je quit invoke TranslateMessage, ADDR msg invoke DispatchMessage, ADDR msg jmp msgloop quit: invoke KillTimer, hWnd, 1 invoke DestroyWindow, hWnd invoke UnregisterClass, offset szClassName, hInstance mov eax, msg.wParam ret WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM cmp uMsg, WM_CREATE je wmcreate cmp uMsg, WM_TIMER je wmtimer cmp uMsg, WM_PAINT je wmpaint cmp uMsg, WM_DESTROY je wmdestroy jmp defwndproc wmcreate: mov eax, 0 ret wmtimer: ; 获取当前时间 invoke GetTickCount mov tick, eax ; 计算时间差 sub eax, count mov count, tick ; 更新窗口 invoke InvalidateRect, hWnd, NULL, TRUE invoke UpdateWindow, hWnd ret wmpaint: ; 绘制文本 invoke BeginPaint, hWnd, ADDR ps invoke GetClientRect, hWnd, ADDR rect invoke SetTextColor, ps.hdc, 0000FFh invoke SetBkMode, ps.hdc, TRANSPARENT invoke TextOut, ps.hdc, 10, 10, ADDR msg, sizeof msg - 1 invoke wsprintf, ADDR buf, '%d.%03d', count / 1000, count % 1000 invoke TextOut, ps.hdc, 60, 10, ADDR buf, eax invoke EndPaint, hWnd, ADDR ps ret wmdestroy: mov eax, 0 jmp quit defwndproc: invoke DefWindowProc, hWnd, uMsg, wParam, lParam ret szClassName db 'MyWindowClass',0 szTitle db 'My Window',0 buf db 16 dup (?) rect RECT <0, 0, 320, 240> wc WNDCLASSEX ? ps PAINTSTRUCT <> hInstance HINSTANCE ? hWnd HWND ? msg MSG <> count dd 0 tick dd 0 end start ``` 该程序创建了一个窗口,通过设置计时器每1毫秒触发一次回调函数来实现计时和显示。在回调函数中,通过调用`GetTickCount`函数获取当前时间,计算时间差,并更新窗口显示。窗口绘制使用了Windows API中的GDI函数。 注意:该程序只是一个简单的示例,实际使用中可能需要更复杂的逻辑来处理计时和显示,同时需要注意计时器的精度和稳定性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值