【32asm】04 - 重定位

来源:https://www.cnblogs.com/awmking/archive/2023/01/06/17029334.html
-Advertisement-
Play Games

目標:在掃雷中註入一個messagebox彈窗; 方法:打開一個進程(掃雷的進程),申請記憶體,寫入messagebox; 另外啟動一個線程,讓整個代碼跑起來 項目創建 註入代碼 .586 .model flat,stdcall option casemap:none include windows. ...


目標:在掃雷中註入一個messagebox彈窗;

方法:打開一個進程(掃雷的進程),申請記憶體,寫入messagebox;

另外啟動一個線程,讓整個代碼跑起來

項目創建

註入代碼

.586
.model flat,stdcall
option casemap:none

   include windows.inc
   include user32.inc
   include kernel32.inc
   
   includelib user32.lib
   includelib kernel32.lib


WinMain proto :DWORD,:DWORD,:DWORD,:DWORD


.data
    g_szWinmine db "掃雷", 0
    g_szKernel db "Kernel32", 0
    g_szLoadLibrary db "LoadLibraryA", 0
    g_szGetProcAddress db "GetProcAddress", 0
    g_hKer   dd 0
    g_dwPid   dd 0
    g_hProc   dd 0
    g_pAddr   dd 0
    g_dwBytesWrited dd 0
    g_dwOldProc dd 0 
    g_szMsg   db "你被註入了", 0
    g_szTitle db "不要擔心,重啟就行", 0
    
    
.code

MSGBOX:
int 3
invoke MessageBox,NULL,offset g_szMsg,offset g_szTitle, MB_OK

    

start:
    ;打開進程
    invoke FindWindow,NULL,offset g_szWinmine           ;視窗句柄
    invoke GetWindowThreadProcessId,eax,offset g_dwPid  ; 進程id
    invoke OpenProcess,PROCESS_ALL_ACCESS,FALSE,g_dwPid ;打開進程
	mov g_hProc,eax
	
	;申請記憶體
    invoke VirtualAllocEx,g_hProc,NULL,1000h,MEM_COMMIT,PAGE_EXECUTE_READWRITE
    mov g_pAddr,eax
    
    
    ;生成機器碼寫入到申請的記憶體,跨進程寫記憶體
    invoke WriteProcessMemory, g_hProc, g_pAddr, offset MSGBOX, offset start - offset MSGBOX, offset g_dwBytesWrited
	
	; 創建線程,執行代碼
	invoke CreateRemoteThread,g_hProc,NULL,0,g_pAddr,NULL,NULL,NULL
	
	invoke ExitProcess,eax
	end start

掃雷的可執行文件放進去,先執行了掃雷,在執行程式,導致直接掃雷崩潰,,,,,,,,

調試分析過程記錄

在chongdingwei.exe中記憶體申請成功,在02770000處;

在winmine.exe中找到這個位置查看,4個push和1個call;

在chongdingwei.exe再查看

查看chongdingwei.exe,找到二進位數據,4個push(00結尾)和1個call;

在winmine.exe的02770000處下斷點,當chongdingwei.exe啟動線程時,在這個位置斷下來

這裡重新開始跑了,申請的地址變了,不過不影響分析,繼續進行,新申請的地址 02b60000

當chongdingwei.exe啟動線程

在winmine.exe的02770000處這個位置斷下來;

繼續單步走一下就崩潰了; 這裡是怎麼看出來崩掉的 ?????????

查看日誌: 查看 - 記錄

這裡日誌沒有報錯信息

用x64dbg打開調一下,這裡的日誌信息比較詳細;

winmine.exe用x64dbg打開,先讓進程跑起來;

在radasm生成代碼的前面加個int 3,當斷點用,到int3的時候調試器就會停下來的,就能知道下斷點的位置;

radasm中 構建-運行,主線程調用,winmine.exe在x64dbg斷下來

f8單步,直接崩潰;

下個斷點,(將斷點int 3,改為Nop, 繼續走)

走到call的位置就掛掉了

4個push,中間兩個是兩個字元串: 右鍵-記憶體視窗中轉到-這個地址 ;發現並不是傳入的字元串

字元串沒有拷貝過來,而且地址不對,地址在原進程中寫成固定值了;

這個字元串地址是原進程中的地址,並沒有拷貝到winmine.exe中

打開chongdingwei.exe,看一下字元串的位置

查看字元串: 右鍵 - 數據視窗跟隨 - 立即數

分析完成,開始處理問題;

問題處理

字元串問題處理: 先把字元串帶到winmine.exe線程:

修改用這種方式

先讓winmine.exe用x64dbg打開,程式跑起來;

雙擊chongdingwei.exe

程式斷下來

下斷點,查看字元串是否帶進來了

字元串從02ac0003開始的

可以看到字元串代進來了;

但是push的地址不對,push的地址應該是在jmp的位置;

因為這個地址是寫的註入代碼時記憶體的地址,拷貝到主線程後,機器碼沒有變化,這個地址還是 原來的地址。

地址需要動態算出來

地址問題處理:發現主線程地址與註入代碼地址差是一樣的(偏移值相同)。 動態算出來地址

當代碼跑起來的時候,需要算出來在哪個地址;

用相同指令位置的值來相減就可以;

偏移值: 獲取當前的EIP ,減去之前的offset地址值

獲取當前指令在新的記憶體中地址:

call 會把下一條指令的地址壓棧,標號正好在pop指令上,所以就把pop ebx指令地址壓棧,然後再執行pop ebx,此時ebx就是這條指令的地址(eip的值);

獲取偏移:

新地址 - 原先的地址

invoke不能用了,否則地址仍然是固定的,但地址要實時取,所以用push四個參數。

先讓winmine.exe用x64dbg打開,程式跑起來;

雙擊chongdingwei.exe

程式斷下來,可以看到各個差值是正確的

但是這個call的地址值為空,這裡無法調用messagebox

messagebox地址也不能寫死,否則不能做到通用;

看一下chongdingwei.exe的call怎麼調用messagebox的

call 跑到jmp的位置,jmp跳到messagebox函數地址的,是一個偏移

同一臺電腦上,不同進程中的dll地址相同,包括kernal32,user32,那麼LoadLib,GetProcAddr,地址也是一樣的; 模塊地址一樣,那麼導出函數地址一樣

假設不同進程中地址不一樣,獲取到LoadLibary,GetProcAddress地址,就獲取任何api的地址

未使用巨集的時候,代碼保存一下

.586
.model flat,stdcall
option casemap:none

   include windows.inc
   include user32.inc
   include kernel32.inc
   
   includelib user32.lib
   includelib kernel32.lib


WinMain proto :DWORD,:DWORD,:DWORD,:DWORD

spush macro x
    mov eax, offset x
    add eax,ebx
    push eax
endm

scall macro x
    mov eax, offset x
    add eax,ebx
    call dword ptr[eax]
endm

smov macro x,reg
    mov eax, offset x
    add eax,ebx
    mov dword ptr [eax],reg
endm



.data
    g_szWinmine db "掃雷", 0
    g_szKernel db "Kernel32", 0
    g_szLoadLibrary db "LoadLibraryA", 0
    g_szGetProcAddress db "GetProcAddress", 0
    g_hKer   dd 0
    g_dwPid   dd 0
    g_hProc   dd 0
    g_pAddr   dd 0
    g_dwBytesWrited dd 0
    g_dwOldProc dd 0 


.code

MSGBOX:
int 3

jmp COMEONBABY
g_szMsg   db "你被註入了", 0
g_szTitle db "不要擔心,重啟就行", 0
g_szUser32 db "user32",0  ;拿到user32基址
g_szMsgBox db "MessageBoxA",0

g_pfnLoadLib   dd 0
g_pfnGetProcAddr dd 0
g_pfnMessageBox dd 0
g_hUser32    dd 0

COMEONBABY:
call NEXT
NEXT:
pop ebx    ; 獲取新記憶體地址
sub ebx, offset NEXT ;獲取偏移

mov edx, offset g_pfnLoadLib
add edx,ebx ;LoadLibary地址

mov eax, offset g_szUser32
add eax, ebx
push eax

call dword ptr [edx]; 調用LoadLibary,載入User32模塊

mov edx, offset g_hUser32
add edx,ebx
mov dword ptr [edx],eax

mov edx, offset g_pfnGetProcAddr
add edx,ebx ;GetProcAddress地址

mov eax, offset g_szMsgBox
add eax,ebx
push eax 

call dword ptr[eax] ;調用GetProcAddress,獲取MessageBox地址

mov edx, offset g_pfnMessageBox
add edx, ebx
mov dword ptr [edx], eax

push MB_OK

mov eax, offset g_szTitle
add eax,ebx  ;當前地址+偏移地址
push eax

mov eax, offset g_szMsg
add eax,ebx 
push eax

push NULL


mov edx, offset g_pfnMessageBox
add edx, ebx
call dword ptr [edx] ; 調用MessageBox

ret 4 ; 執行之後從線程函數中返回,線程函數一個參數,參數平棧

;invoke MessageBox,NULL,offset g_szMsg,offset g_szTitle, MB_OK

    

start:
    ;打開進程
    invoke FindWindow,NULL,offset g_szWinmine           ;視窗句柄
    invoke GetWindowThreadProcessId,eax,offset g_dwPid  ; 進程id
    invoke OpenProcess,PROCESS_ALL_ACCESS,FALSE,g_dwPid ;打開進程
	mov g_hProc,eax
	
	;申請記憶體
    invoke VirtualAllocEx,g_hProc,NULL,1000h,MEM_COMMIT,PAGE_EXECUTE_READWRITE
    mov g_pAddr,eax
    
    
    ;生成機器碼寫入到申請的記憶體,跨進程寫記憶體
    invoke WriteProcessMemory, g_hProc, g_pAddr, offset MSGBOX, offset start - offset MSGBOX, offset g_dwBytesWrited
	
	; 創建線程,執行代碼
	invoke CreateRemoteThread,g_hProc,NULL,0,g_pAddr,NULL,NULL,NULL
	
	invoke ExitProcess,eax

end start

使用巨集代碼記錄

.586
.model flat,stdcall
option casemap:none

   include windows.inc
   include user32.inc
   include kernel32.inc
   
   includelib user32.lib
   includelib kernel32.lib


WinMain proto :DWORD,:DWORD,:DWORD,:DWORD

spush macro x
    mov eax, offset x
    add eax,ebx
    push eax
endm

scall macro x
    mov eax, offset x
    add eax,ebx
    call dword ptr[eax]
endm

smov macro x,reg
    mov eax, offset x
    add eax,ebx
    mov dword ptr [eax],reg
endm



.data
    g_szWinmine db "掃雷", 0
    g_szKernel db "Kernel32", 0
    g_szLoadLibrary db "LoadLibraryA", 0
    g_szGetProcAddress db "GetProcAddress", 0
    g_hKer   dd 0
    g_dwPid   dd 0
    g_hProc   dd 0
    g_pAddr   dd 0
    g_dwBytesWrited dd 0
    g_dwOldProc dd 0 


.code

MSGBOX:
int 3

jmp COMEONBABY
g_szMsg   db "你被註入了", 0
g_szTitle db "不要擔心,重啟就行", 0
g_szUser32 db "user32",0  ;拿到user32基址
g_szMsgBox db "MessageBoxA",0


g_pfnLoadLib   dd 0
g_pfnGetProcAddr dd 0
g_pfnMessageBox dd 0
g_hUser32    dd 0

COMEONBABY:
call NEXT
NEXT:
pop ebx    ; 獲取新記憶體地址
sub ebx, offset NEXT ;獲取偏移


;載入user32.dll
spush offset g_szUser32
scall g_pfnLoadLib

mov edx,eax
smov g_hUser32,edx


;獲取MessageBox地址
spush offset g_szMsgBox
scall g_pfnGetProcAddr

mov edx,eax
smov g_pfnMessageBox,edx


;調用MessageBox
push MB_OK
spush offset g_szTitle
spush offset g_szMsg
push NULL
scall offset g_pfnMessageBox

ret 4 ; 執行之後從線程函數中返回,線程函數一個參數,參數平棧

;invoke MessageBox,NULL,offset g_szMsg,offset g_szTitle, MB_OK

    

start:
    ;打開進程
    invoke FindWindow,NULL,offset g_szWinmine           ;視窗句柄
    invoke GetWindowThreadProcessId,eax,offset g_dwPid  ; 進程id
    invoke OpenProcess,PROCESS_ALL_ACCESS,FALSE,g_dwPid ;打開進程
	mov g_hProc,eax
	
	;寫入loadLibrary和GetProcAddress地址
	invoke GetModuleHandle,offset g_szKernel
	mov g_hKer,eax
	
	invoke GetProcAddress,g_hKer,offset g_szLoadLibrary
	mov g_pfnLoadLib,eax
	
	invoke GetProcAddress,g_hKer,offset g_szGetProcAddress
	mov g_pfnGetProcAddr,eax
	
	
	
	
	
	;申請記憶體
    invoke VirtualAllocEx,g_hProc,NULL,1000h,MEM_COMMIT,PAGE_EXECUTE_READWRITE
    mov g_pAddr,eax
    
    
    ;生成機器碼寫入到申請的記憶體,跨進程寫記憶體
    invoke WriteProcessMemory, g_hProc, g_pAddr, offset MSGBOX, offset start - offset MSGBOX, offset g_dwBytesWrited
	
	; 創建線程,執行代碼
	invoke CreateRemoteThread,g_hProc,NULL,0,g_pAddr,NULL,NULL,NULL
	
	invoke ExitProcess,eax

end start

地址寫數據的時候報C00005,401034代碼區,地址寫到代碼區就完蛋

代碼需要改一下屬性

主進程也報錯異常了;

發現

參數不夠的表現

代碼修改,messageBox增加參數

spush offset g_szMsgBox

spushval g_hUser32

scall g_pfnGetProcAddr

註入成功

完整代碼記錄

.586
.model flat,stdcall
option casemap:none

   include windows.inc
   include user32.inc
   include kernel32.inc
   
   includelib user32.lib
   includelib kernel32.lib
   
WinMain proto :DWORD,:DWORD,:DWORD,:DWORD
spush macro x
    mov eax, offset x
    add eax, ebx
    push eax
endm

spushval macro x
    mov eax, offset x
    add eax, ebx
    push dword ptr[eax]
endm

scall macro x
    mov eax, offset x
    add eax, ebx
    call dword ptr[eax]
endm

smov macro x, reg
    mov eax, offset x
    add eax, ebx
    mov dword ptr [eax], reg
endm

.data

g_szWinmine db "掃雷", 0
g_szKernel db "Kernel32", 0
g_szLoadLibrary db "LoadLibraryA", 0
g_szGetProcAddress db "GetProcAddress", 0
g_hKer   dd 0
g_dwPid   dd 0
g_hProc   dd 0
g_pAddr   dd 0
g_dwBytesWrited dd 0
g_dwOldProc dd 0 

.code
MSGBOX:

jmp EXECODE
g_szMsg   db "你被註入了", 0
g_szTitle db "不要擔心,重啟就行", 0

g_szUser32 db "user32", 0
g_szMsgBox db "MessageBoxA", 0

g_pfnLoadLib        dd 0 ;三個函數地址,在主函數賦值了。
g_pfnGetProcAddr    dd 0
g_pfnMessageBox     dd 0

g_hUser32           dd 0 ;句柄


EXECODE:

call NEXT
NEXT:
pop ebx
sub ebx,offset NEXT  ;獲取偏移

;----------------------------------------messagebox函數在user32.dll里-------------------
;載入user32.dll
spush offset g_szUser32
scall g_pfnLoadLib

mov edx, eax
smov g_hUser32, edx

;獲取MessageBox地址
spush   offset g_szMsgBox
spushval g_hUser32
scall g_pfnGetProcAddr

mov edx, eax
smov g_pfnMessageBox, edx

;----------------------------------------調用messagebox函數-------------------
push MB_OK
spush offset g_szMsg
spush offset g_szTitle
push NULL
scall offset g_pfnMessageBox
ret 4                 ;線程過程函數有一個參數
;invoke MessageBox, NULL, offset g_szMsg, offset g_szTitle, MB_OK
;---------------------------------------------------------------------------------


start:
	
    invoke FindWindow,NULL,offset g_szWinmine  ;視窗句柄,返回到了eax
    invoke GetWindowThreadProcessId,eax,offset g_dwPid ;進程id
    invoke OpenProcess,PROCESS_ALL_ACCESS,FALSE,g_dwPid ;打開進程
    mov g_hProc,eax                                    ;進程句柄
    
    ;改代碼段屬性
    invoke VirtualProtect, offset MSGBOX, offset start - offset MSGBOX, PAGE_EXECUTE_READWRITE, offset g_dwOldProc
    
    
    ;寫入LoadLibaray和GetProcAddress地址;LoadLibaray載入user32.dll,GetProcAddress得到messagebox地址。
    invoke GetModuleHandle, offset g_szKernel
    mov g_hKer, eax
    
    invoke GetProcAddress,g_hKer,offset g_szLoadLibrary
    mov g_pfnLoadLib, eax
    
    invoke GetProcAddress, g_hKer, offset g_szGetProcAddress
    mov g_pfnGetProcAddr, eax
    
    ;申請記憶體
    invoke VirtualAllocEx,g_hProc,NULL,1000h,MEM_COMMIT,PAGE_EXECUTE_READWRITE
    mov g_pAddr,eax
    
    invoke VirtualProtect, offset MSGBOX, offset start - offset MSGBOX, g_dwOldProc, offset g_dwOldProc
    
    ;寫入機器碼
    invoke WriteProcessMemory,g_hProc,g_pAddr,offset MSGBOX, offset start - offset MSGBOX, offset g_dwBytesWrited
    
    ;創建線程,執行代碼
    invoke CreateRemoteThread, g_hProc, NULL,0, g_pAddr, NULL, NULL, NULL
    
	invoke ExitProcess,eax


end start


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 我國目前並未出台專門針對網路爬蟲技術的法律規範,但在司法實踐中,相關判決已屢見不鮮,K 哥特設了“K哥爬蟲普法”專欄,本欄目通過對真實案例的分析,旨在提高廣大爬蟲工程師的法律意識,知曉如何合法合規利用爬蟲技術,警鐘長鳴,做一個守法、護法、有原則的技術人員。 案情介紹 據魔蝎科技官網(現已無法打開)介 ...
  • 向下相容特性是軟體開發系統的一個重要指標,它是指一個新的系統或者軟體能夠與舊的系統或軟體相容並正常運行。這意味著舊系統或軟體可以在新系統或軟體中使用,而不會出現問題。向下相容對於提高軟體或系統的可用性非常重要,因為它允許用戶在不更換舊系統或軟體的情況下使用新系統或軟體。 我們知道MacOS系統從Mo ...
  • 本文作者:知知行行 本文鏈接:https://www.cnblogs.com/loronoa/p/16566818.html docker容器網路 Docker在安裝後自動提供3種網路,可以使用docker network ls命令查看 [root@localhost ~]# docker netw ...
  • 創建Django 項目前置條件:已完成Python環境和PyCharm安裝 Django的安裝和項目的創建 | 在命令行輸入pip 命令安裝 pip install -i https://pypi.douban.com/simple django 或 指定相應的django版本: pip insta ...
  • 本實例使用了工具包SKIT.FlurlHttpClient.Wechat.TenpayV3(github:https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient.Wechat) 示例中的_repositoryWrapper的相關使用是我們 ...
  • 1 ProXmoX-VE簡介 PVE(ProXmoX VE)是一個開源的虛擬化管理軟體,類似ESXI,用戶可以通過網頁的方式來管理伺服器,使用kvm以及lxc技術運行虛擬機,同時也提供了一些集群和HA等功能。 2 安裝 2.1準備工作 首先準備好安裝的鏡像proxmox-ve_7.3-1下載地址:h ...
  • 技術方案: 1.運行時使用.Net Framework4.6框架,界面使用WPF與Chromium。 2.上位機與下位機使用串口對接每家設備協議,上位機與UI使用WebSocket通訊。 3.資料庫使用SQLite和localStorage。 單機版V1.0 界面清新、操作簡單。 支持地磅秤、智能電 ...
  • 由於.NET 中是讓垃圾收集器Garbage Collector (簡稱GC)刪除未使用的對象。但是,由於GC只是不時地刪除未使用的對象,因此同時使用的記憶體會增加。更重要的是,對於GC來說,HALCON 的標誌性變數(圖像、區域……)似乎相當“小”,因為它們只包含對(在許多情況下相當大)標誌性對象的 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...