PC微信端讀取聯繫人有三種常規方法:javascript
其實前兩種方法只是利用微信啓動後已經讀取聯繫人放到內存。第一種是攔截過程,第二種是直接獲取內存的結果。java
找CALL請看:https://blog.csdn.net/qq_3847...c++
我就不復述了,我也是小白,也是一步一步按照博客來操做的。我就直接給當前最新版本(2.8.0.121)的須要hook的地址偏移:0x479F07,若是不想本身找CALL的話,能夠直接用OD跳轉到 WeChatWin.dll + 0x479F07
這個地址。已經知道須要hook的地址,只須要用c++寫dll而後注入到微信進程就能夠獲得全部的聯繫人信息了(這個call會在登陸時被調用屢次,因此須要登陸前就注入dll)數據庫
成品軟件和dll(軟件是用aardio寫的,dll是用c++寫的):https://www.lanzous.com/iakfpch微信
效果圖:spa
相比於第一種方法,這個更簡單,連寫dll注入都不須要。只要讀內存中的數據就行。.net
首先咱們須要找到二叉樹的根節點地址,方法請看:https://www.jianshu.com/p/b55... (環境聲太吵,人說話聲音有點小,不過講的不錯)3d
最新版本(2.8.0.121)二叉樹根節點的地址:[[WeChatwin.dll + 0x161CF54]+0x28+0x84] + 0x4
,中括號表示取地址裏面的值。這個地址的偏移也是經過第一個方法的call找出來的,並且第一個方法中的call進去的代碼就是經過傳入的wxid來循環遍歷二叉樹來獲取該wxid對應的好友數據。code
咱們看一下call裏面的彙編代碼段:
而後用aardio來實現就是:orm
import process; import console; getBTree = function(prcs, esi){ //前面不加var表示全局變量 if (!prcs.readNumber(esi + 0xD, "byte")){ //cmp byte ptr ds:[esi+0xD],0x0 //wxid wxidAddr = prcs.readNumber(esi + 0x10) //獲取wxid地址 wxidLen = prcs.readNumber(esi + 0x14) //獲取wxid長度 wxid = prcs.readStringUtf16(wxidAddr, wxidLen) // 讀取Unicode字符串 wxid = string.fromUnicode(wxid) //將Unicode字符串轉換爲utf-8 //微信號 微信號地址 = prcs.readNumber(esi + 0x44) 微信號長度 = prcs.readNumber(esi + 0x48) 微信號 = prcs.readStringUtf16(微信號地址, 微信號長度) 微信號 = string.fromUnicode(微信號) //暱稱 暱稱地址 = prcs.readNumber(esi + 0x8C) 暱稱長度 = prcs.readNumber(esi + 0x8C + 0x4) 暱稱 = prcs.readStringUtf16(暱稱地址, 暱稱長度) 暱稱 = string.fromUnicode(暱稱) //備註 備註地址 = prcs.readNumber(esi + 0x78) 備註長度 = prcs.readNumber(esi + 0x78 + 0x4) 備註 = prcs.readStringUtf16(備註地址, 備註長度) 備註 = string.fromUnicode(備註) //v1 v1Addr = prcs.readNumber(esi + 0x58) v1Len = prcs.readNumber(esi + 0x5C) v1 = prcs.readStringUtf16(v1Addr, v1Len) v1 = string.fromUnicode(v1) //未知a1 a1Addr = prcs.readNumber(esi + 0xCC) a1Len = prcs.readNumber(esi + 0xD0) a1 = prcs.readStringUtf16(a1Addr, a1Len) //未知a2 a2Addr = prcs.readNumber(esi + 0xE0) a2Len = prcs.readNumber(esi + 0xE4) a2 = prcs.readStringUtf16(a2Addr, a2Len) console.writeText(string.format("%s | %s | %s | %s", tostring(wxid), tostring(微信號), tostring(暱稱), tostring(備註)) + '\n') 左節點地址 = prcs.readNumber(esi) getBTree(prcs, 左節點地址) 右節點地址 = prcs.readNumber(esi + 0x8) getBTree(prcs, 右節點地址) } } var readData = function(){ console.open() prcs = process.find("WeChat.exe") if (null == prcs){ console.writeText('未找到微信進程,請先打開微信登陸後操做!') return } wechatwinAddr = prcs.getModuleBaseAddress('WeChatWin.dll') ecx = prcs.readNumber(wechatwinAddr + 0x161CF54) + 0x28 + 0x84 ebx = prcs.readNumber(ecx) //mov ebx,dword ptr ds:[ecx] esi = prcs.readNumber(ebx + 0x4) //mov esi,dword ptr ds:[ebx+0x4] esi也就是二叉樹的根節點 getBTree(prcs, esi) console.pause('按任意鍵關閉!') } readData()
彙編代碼中作了不少比較,是由於它要對比傳入的微信ID和內存中的數據,而咱們全都要則不須要對比,直接遞歸讀取二叉樹的左右節點便可。效果就不放了,本身下載aardio運行一遍就行。