日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

win32 masm32 汇编学习 及 远程线程实例

發布時間:2025/3/20 编程问答 8 豆豆
生活随笔 收集整理的這篇文章主要介紹了 win32 masm32 汇编学习 及 远程线程实例 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
"門“ 指向某個優先級高的程序所規定的入口點,所有優先級低的程序調用優先級高的程序只能通過門重定向
門:中斷門,自陷門,任務門。


masm32.zip
copy D:\Program Files\Microsoft Visual Studio\VC98\Bin\nmake.exe to ?***\masm32\bin


相應cmd設置臨時環境變量
@echo off
set include=f:\masm32\Include;D:\Program Files\Microsoft Visual Studio\VC98\Include;D:\Program Files\Microsoft Visual Studio\VC98\MFC\Include
set lib=f:\masm32\lib
set path=f:\masm32\bin;%path%
@echo on


\**\nmake


.model flat ? MASM自動為各段寄存器做了如下定義:
ASSUME cs:FLAT,ds:FLAT,ss:flat,es:flat,fs:error,gs:error


全部段源程序結構:
.386
.model flat,stdcall
option casemap:none
< Include 文件定義>
.stack [堆棧段大小]
.data
<一些初始化過的變量定義>
.data? ;不會占用EXE文件空間
<一些沒初始化過的變量定義>
.const
<一些常量定義>
.code
<代碼>
<開始標號>
<其他語句>
end 開始標號


invoke 不是80x86的偽指令,它只是MASM編譯器的偽指令,實現push參數和call函數名而已。
對匯編而言,所有參數和返回值 只有一個dword類型,所以要么是簡單類型,要么是指針。
返回值放在eax中


函數名 proto [距離] [語言] [參數1]:數據類型,[參數2]:數據類型,....
proto:函數聲明偽指令
距離:NEAR,FAR...(WIN32只有只有一個平坦的段,無所謂距離,所以忽略)
語言:.model定義的默認值
對于WIN32它只關注參數個數,參數名為是提高可讀性
MessageBox Proto hWnd:dword,lpText:dword,lpCaption:dword,uType:dword
MessageBox Proto ?:dword,:dword,:dword,:dword ?
其實這兩定義是一樣的


只有windows NT才完全支持Unicode,
if UNICODE
MessageBox equ <MessageBoxW>
else
MessageBox equ <MessageBoxA>
endif


//@@做標號
@F本指令后第一個@@標號,@B本指令前的第一個@@標號


如果要定義兩個字符串"hello,world!",和"hello agin",則每個字符串后跟回車和換行符,最后以一個0字符結尾,
szText db 'hello,world!',0dh,0ah,'hello agin',0dh,0ah,0


.data? 后面的默認是0,不是隨機的 ?//與這全局變量不同,local后的局部變量起始值是隨機的


MASM用local偽指令來定義局部變量,local偽指令必須proc偽指令后,其他指令開始前。因為變量數量要早確定下來


結構構成員引用:
1: mov eax,strutname.lpfn
2: mov esi,offset strutname
mov eas,[esi+STRUTNAME.lpfn]
3: mov esi,offset strutname
assume esi:ptr STRUTNAME
mov eax,[esi].lpfn
...
assume esi:nothing




.data
bTest1 db 12h
wTest2 dw 1234h


mov ax,bTest1 ;ax = 3412h
movzx ax,bText1 ;ax = 0012h movsx:帶符號擴展


sizeof/lengthof偽指令
如果hello world分兩行定義:
szHello db 'hello',odh,oah
db 'world',0
sizeof szHello為7,原因masm中變量只認一行,db 'world',0 實際上是沒有名稱的數據定義。


獲取變量地址:
全局變量:mov 寄存器,offset 變量名 ;編譯時
局部變量:lea ? ?寄存器,[ebp-4] ;運行時
參數局部變量:addr 參數變量
對局部變量取地址的時候,addr偽操作只能用在invoke的參數中,addr實際是先取地址到eax,再代替到參數里
invoke Test,eax,addr szHello ;錯誤
翻譯如下:
lea eax,addr szHello
push eax
push eax ;已經被上面覆蓋
call Test


invoke Test,addr szHello,eax ;正確


子程序的定義:
子程序名 ?proc [...][...][VARARG]
local 局部變量列表
指令
子程序名 endp
proc后的參數列表中參數不能和全局變量及子程序中局部變量重名,VARARG指些子程序是可變參數;proto為聲明,如上


調用約定有:C, SysCall,StdCall,BASIC,FORTRAN,PASCAL具體找度娘


條件測試語句:==, != , >,>=,<,<=,&,!,&&,||
限制:左邊只能是變量或者寄存器,不能是常量;
表達式兩邊不能同時為變量,但可以同時為寄存器。
分支語句:.if/.elseif/.else/.endif,如果不加點,則變成條件匯編偽操作


循環語句:
.while ?條件測試表達式
指令
[.break [.if 退出條件]]
[.continue]
.endw
或者
.repeat
指令
[.break [.if 退出條件]]
[.continue]
.until 條件測試表達式 (或.untilcxz [條件測試表達式])
上面的相當while循環,下面的相當do...while循環
代碼規范:
參數用_開頭,局部變量用@開頭,內部子程序用_開頭
盡量不要用宏定義,以免影響可讀性
子程序規模不要太大,注釋寫好,指針安全檢查,做好子程序庫以備未來編寫大程序。


第四章:第一個窗口程序
模塊句柄在數值上等于程序在內存中裝入的起始地址,GetMododuleHandle,模 塊句柄便于訪問程度中的各種資源。
postmessage/sendmessage:
當消息中用到指針時,postmessage函數來發送的消息都不會成功。




10.1.4
windows的“堆”分為默認堆和私有堆兩種。默認堆是在程序初始化時由OS自動創建的,所有的標準的內存管理函數都是在默認堆中申請內存的;而私有堆相當于是在默認堆中保留了一大塊內存,
默認堆只有一個私有堆可以有多個,默認堆可以直接使用,而私有堆必須先創建。
如果多個模塊在默認堆中使用內存會交叉排序,一個模塊越界可以很難找到問題,如果多個模塊在各自的私有堆,越界更容易定位。
私有堆創建函數heapcreate/heapdestory
私有堆中分配和釋放內存塊heapalloc/heaplock/....


在程序運行的時候,進程中每個地址都可以牌下列3種狀態的1種中:
占用狀態:線程地址已映射物理內存,也稱已提交狀態
自由狀態:沒有映射到物理內存,線程地址沒有被使用 //進程剛開始的起始狀態
保留狀態:雖然沒有映射到物理內存,但它不會被使用,直到希望使用他為止




當使用上面的標準內存管理函數時,用戶無法指定內存位于哪個線程地址,使用virtual開頭的虛擬內存管理函數可以做到這一點。如virtualalloc


VirtualAllocEx/CreateRemoteThread相比 Virtualalloc/createthread多了個hprocess,針對相應進程操作
virtualallocex需要對相應進程有process_vm_operation權限
?
遠程線程存在:重定位和函數的導入問題
對高級語言不可能解決重定位問題,因為沒辦法在機器碼級別上操作,c語言也沒有辦法,通過注入dll繞過去,因為裝載DLL會自動重定位


dwVar dd
call @F
@@:
pop ebx
sub ebx,offset @B
mov eax,[ebx+offset dwVar]


:00401000 00000000 BYTE 4 DUP(0)
:00401004 EB00000000 call 00401009
:00401009 5B pop ebx
:0040100A 81EB09104000 sub ebx,00401009
:00401010 8B8300104000 mov eax, dword ptr [ebx+00401000]


當這段代碼移動00401000的位置時如下:
:00801000 00000000 BYTE 4 DUP(0)
:00801004 EB00000000 call 00801009
:00801009 5B pop ebx //此時ebx為:00801009
:0080100A 81EB09104000 sub ebx,00401009
:00801010 8B8300104000 mov eax, dword ptr [ebx+00401000]


遠程代碼用的win32 api,api又存在于是dll中,同時dll裝載基地不同,api函數地址也不同,所以手動完成:
1. loadlibary 使用的dll
2. getprocaddress api函數


其中1,2用到dll名字和api函數名都要采用上面重定位的方法保存好




遠程線程創建步驟:
1.VirtualAllocEx申請目標進程的一塊內存, 要有hProcess有 PROCESS_VM_OPERATION, 內存塊應該有PAGE_EXECUTE_READWRITE屬性
2.writeProcessMemory寫入代碼及數據
3.CreateRemoteThread ? 要hProcess有PROCESS_CREATE_THREAD權限 //remotethread code and data ; RemoteCode.asm ; 一段自定位的代碼,可以用來創建一個窗口 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ; ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> REMOTE_CODE_START equ this byte_lpLoadLibrary dd ? ;導入函數地址表 _lpGetProcAddress dd ? _lpGetModuleHandle dd ?_lpDestroyWindow dd ? _lpPostQuitMessage dd ? _lpDefWindowProc dd ? _lpLoadCursor dd ? _lpRegisterClassEx dd ? _lpCreateWindowEx dd ? _lpShowWindow dd ? _lpUpdateWindow dd ? _lpGetMessage dd ? _lpTranslateMessage dd ? _lpDispatchMessage dd ?_hInstance dd ? _hWinMain dd ? _szClassName db 'RemoteClass',0 _szCaptionMain db 'RemoteWindow',0 _szDllUser db 'User32.dll',0 _szDestroyWindow db 'DestroyWindow',0 _szPostQuitMessage db 'PostQuitMessage',0 _szDefWindowProc db 'DefWindowProcA',0 _szLoadCursor db 'LoadCursorA',0 _szRegisterClassEx db 'RegisterClassExA',0 _szCreateWindowEx db 'CreateWindowExA',0 _szShowWindow db 'ShowWindow',0 _szUpdateWindow db 'UpdateWindow',0 _szGetMessage db 'GetMessageA',0 _szTranslateMessage db 'TranslateMessage',0 _szDispatchMessage db 'DispatchMessageA',0,0 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> _RemoteThread proc uses ebx edi esi lParamlocal @hModulecall @F@@:pop ebxsub ebx,offset @B ;********************************************************************_invoke [ebx + _lpGetModuleHandle],NULLmov [ebx + _hInstance],eaxlea eax,[ebx + offset _szDllUser]_invoke [ebx + _lpGetModuleHandle],eaxmov @hModule,eaxlea esi,[ebx + offset _szDestroyWindow]lea edi,[ebx + offset _lpDestroyWindow].while TRUE_invoke [ebx + _lpGetProcAddress],@hModule,esimov [edi],eaxadd edi,4@@:lodsbor al,aljnz @B.break .if ! byte ptr [esi].endw ;********************************************************************call _WinMainret_RemoteThread endp ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> _ProcWinMain proc uses ebx edi esi,hWnd,uMsg,wParam,lParamcall @F@@:pop ebxsub ebx,offset @B ;********************************************************************mov eax,uMsg.if eax == WM_CLOSE_invoke [ebx + _lpDestroyWindow],hWnd_invoke [ebx + _lpPostQuitMessage],NULL ;********************************************************************.else_invoke [ebx + _lpDefWindowProc],hWnd,uMsg,wParam,lParamret.endif ;********************************************************************xor eax,eaxret_ProcWinMain endp ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> _ZeroMemory proc _lpDest,_dwSizepush edimov edi,_lpDestmov ecx,_dwSizexor eax,eaxcldrep stosbpop ediret_ZeroMemory endp ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> _WinMain proc uses ebx esi edi _lParamlocal @stWndClass:WNDCLASSEXlocal @stMsg:MSGcall @F@@:pop ebxsub ebx,offset @B ;********************************************************************invoke _ZeroMemory,addr @stWndClass,sizeof @stWndClass_invoke [ebx + _lpLoadCursor],0,IDC_ARROWmov @stWndClass.hCursor,eaxpush [ebx + _hInstance]pop @stWndClass.hInstancemov @stWndClass.cbSize,sizeof WNDCLASSEXmov @stWndClass.style,CS_HREDRAW or CS_VREDRAWlea eax,[ebx + offset _ProcWinMain]mov @stWndClass.lpfnWndProc,eaxmov @stWndClass.hbrBackground,COLOR_WINDOW + 1lea eax,[ebx + offset _szClassName]mov @stWndClass.lpszClassName,eaxlea eax,@stWndClass_invoke [ebx + _lpRegisterClassEx],eax ;******************************************************************** ; 建立并顯示窗口 ;********************************************************************lea eax,[ebx + offset _szClassName]lea ecx,[ebx + offset _szCaptionMain]_invoke [ebx + _lpCreateWindowEx],WS_EX_CLIENTEDGE,eax,ecx,\WS_OVERLAPPEDWINDOW,\100,100,600,400,\NULL,NULL,[ebx + _hInstance],NULLmov [ebx + _hWinMain],eax_invoke [ebx + _lpShowWindow],[ebx + _hWinMain],SW_SHOWNORMAL_invoke [ebx + _lpUpdateWindow],[ebx + _hWinMain] ;******************************************************************** ; 消息循環 ;********************************************************************.while TRUElea eax,@stMsg_invoke [ebx + _lpGetMessage],eax,NULL,0,0.break .if eax == 0lea eax,@stMsg_invoke [ebx + _lpTranslateMessage],eaxlea eax,@stMsg_invoke [ebx + _lpDispatchMessage],eax.endwret_WinMain endp REMOTE_CODE_END equ this byte REMOTE_CODE_LENGTH equ offset REMOTE_CODE_END - offset REMOTE_CODE_START ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> //createremotethread code ; RemoteThread.asm ; 向 Explorer.exe 進程中嵌入一段遠程執行的代碼 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ; 使用 nmake 或下列命令進行編譯和鏈接: ; ml /c /coff RemoteThread.asm ; rc RemoteThread.rc ; Link /subsystem:windows RemoteThread.obj RemoteThread.res ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>.386.model flat, stdcalloption casemap :none ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ; Include 文件定義 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> include windows.inc include user32.inc includelib user32.lib include kernel32.inc includelib kernel32.lib include Macro.inc ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ; 數據段 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>.data? lpLoadLibrary dd ? lpGetProcAddress dd ? lpGetModuleHandle dd ? dwProcessID dd ? dwThreadID dd ? hProcess dd ? lpRemoteCode dd ?.const szErrOpen db '無法打開遠程線程!',0 szDesktopClass db 'Progman',0 szDesktopWindow db 'Program Manager',0 szDllKernel db 'Kernel32.dll',0 szLoadLibrary db 'LoadLibraryA',0 szGetProcAddress db 'GetProcAddress',0 szGetModuleHandle db 'GetModuleHandleA',0 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>.code ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>include RemoteCode.asmstart:invoke GetModuleHandle,addr szDllKernelmov ebx,eaxinvoke GetProcAddress,ebx,offset szLoadLibrarymov lpLoadLibrary,eaxinvoke GetProcAddress,ebx,offset szGetProcAddressmov lpGetProcAddress,eaxinvoke GetProcAddress,ebx,offset szGetModuleHandlemov lpGetModuleHandle,eax ;******************************************************************** ; 查找文件管理器窗口并獲取進程ID,然后打開進程 ;********************************************************************invoke FindWindow,addr szDesktopClass,addr szDesktopWindowinvoke GetWindowThreadProcessId,eax,offset dwProcessIDmov dwThreadID,eaxinvoke OpenProcess,PROCESS_CREATE_THREAD or PROCESS_VM_OPERATION or \PROCESS_VM_WRITE,FALSE,dwProcessID.if eaxmov hProcess,eax ;******************************************************************** ; 在進程中分配空間并將執行代碼拷貝過去,然后創建一個遠程線程 ;********************************************************************invoke VirtualAllocEx,hProcess,NULL,REMOTE_CODE_LENGTH,MEM_COMMIT,PAGE_EXECUTE_READWRITE.if eaxmov lpRemoteCode,eaxinvoke WriteProcessMemory,hProcess,lpRemoteCode,\offset REMOTE_CODE_START,REMOTE_CODE_LENGTH,NULLinvoke WriteProcessMemory,hProcess,lpRemoteCode,\ ;遠程代碼及數據放在當前進程的代碼段,不能修改本地的代碼段offset lpLoadLibrary,sizeof dword * 3,NULL ;應該去遍歷目標進程這三個函數。mov eax,lpRemoteCodeadd eax,offset _RemoteThread - offset REMOTE_CODE_STARTinvoke CreateRemoteThread,hProcess,NULL,0,eax,0,0,NULLinvoke CloseHandle,eax.endifinvoke CloseHandle,hProcess.elseinvoke MessageBox,NULL,addr szErrOpen,NULL,MB_OK or MB_ICONWARNING.endifinvoke ExitProcess,NULL ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>end start

總結

以上是生活随笔為你收集整理的win32 masm32 汇编学习 及 远程线程实例的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。