XDCTF 2013 code2 跳出死循環

題目:編寫一個程序(好比kernel module),使附件2.c中的程序跳出死循環。2.c中的代碼以下:
#include 
int main(int argc, char *argv[])
{
int n = 1;
printf(「Address of n :%x\n」,&n);
printf(「My pid is: %d.\n」, getpid());
while(1){
sleep(3); /* sleep for 3 secs */
}
printf(「I break out\n」);
return 0;
}
說明:
此題只需上交實現文檔、源碼。源碼中請以註釋註明平臺、系統。好比32位linux 3.2。
將上述代碼編譯好(不能修改),運行,想辦法令其跳出循環,打印出」I break out\n」。
你的代碼不能調用任何其餘軟件,好比od之類。
若是你知道內核棧、pt_regs結構體、函數棧楨,那麼你頗有可能成功。
成功打印出」I break out\n」但同時引起段錯誤得2/3分。linux

 

屌絲不會linux,因此只能windowswindows

 

思路:debug編譯出上面代碼能夠看到while(1)的反彙編代碼爲mov ecx,1,只需用WriteProcessMemory將1修改成0便可跳出死循環函數

 

反彙編:測試

 1 0040D470 >  55              push ebp
 2 0040D471    8BEC            mov ebp,esp
 3 0040D473    83EC 44         sub esp,44
 4 0040D476    53              push ebx
 5 0040D477    56              push esi
 6 0040D478    57              push edi
 7 0040D479    8D7D BC         lea edi,dword ptr ss:[ebp-44]
 8 0040D47C    B9 11000000     mov ecx,11
 9 0040D481    B8 CCCCCCCC     mov eax,CCCCCCCC
10 0040D486    F3:AB           rep stos dword ptr es:[edi]
11 0040D488    C745 FC 0100000>mov dword ptr ss:[ebp-4],1
12 0040D48F    8D45 FC         lea eax,dword ptr ss:[ebp-4]
13 0040D492    50              push eax
14 0040D493    68 942F4200     push xd_code2.00422F94                   ; ASCII "Address of n :%x
15 "
16 0040D498    E8 83020000     call xd_code2.printf
17 0040D49D    83C4 08         add esp,8
18 0040D4A0    E8 4B000000     call xd_code2._getpid
19 0040D4A5    50              push eax
20 0040D4A6    68 842F4200     push xd_code2.00422F84                   ; ASCII "My pid is: %d.
21 "
22 0040D4AB    E8 70020000     call xd_code2.printf
23 0040D4B0    83C4 08         add esp,8
24 0040D4B3    B9 01000000     mov ecx,1                                ; while(1)
25 0040D4B8    85C9            test ecx,ecx
26 0040D4BA    74 13           je short xd_code2.0040D4CF
27 0040D4BC    8BF4            mov esi,esp
28 0040D4BE    6A 03           push 3
29 0040D4C0    FF15 18A24200   call dword ptr ds:[<&KERNEL32.Sleep>]    ; kernel32.Sleep
30 0040D4C6    3BF4            cmp esi,esp
31 0040D4C8    E8 C33BFFFF     call xd_code2.00401090
32 0040D4CD  ^ EB E4           jmp short xd_code2.0040D4B3
33 0040D4CF    68 1C204200     push xd_code2.0042201C                   ; ASCII "I break out
34 "
35 0040D4D4    E8 47020000     call xd_code2.printf
36 0040D4D9    83C4 04         add esp,4
37 0040D4DC    33C0            xor eax,eax
38 0040D4DE    5F              pop edi
39 0040D4DF    5E              pop esi
40 0040D4E0    5B              pop ebx
41 0040D4E1    83C4 44         add esp,44
42 0040D4E4    3BEC            cmp ebp,esp
43 0040D4E6    E8 A53BFFFF     call xd_code2.00401090
44 0040D4EB    8BE5            mov esp,ebp
45 0040D4ED    5D              pop ebp
46 0040D4EE    C3              retn

 

代碼:spa

 1 #include "stdafx.h"
 2 #include <windows.h>
 3 #include <TlHelp32.h>
 4 #define PID 2200 //每次運行手動修改
 5 BYTE* GetBase(int Pid);
 6 
 7 int _tmain(int argc, _TCHAR* argv[])
 8 {
 9     BYTE *base = GetBase(PID);
10 
11     //printf_s("%x", base);
12     HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);
13     byte NewCode = 0;
14 
15     //測試發現地址不會變,都爲0x40D4B4,故GetBase函數都不須要
16     if (WriteProcessMemory(hProcess, base + 0xD4B4, &NewCode, 1, NULL))
17     {
18         printf_s("Write Success!\n");
19     }
20     
21     getchar();
22     return 0;
23 }
24 
25 BYTE* GetBase(int Pid)
26 {
27     BYTE *result = NULL;
28     HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, Pid);
29     if (hSnap == INVALID_HANDLE_VALUE)
30     {
31         printf_s("CreateToolhelp32Snapshot failed\n");
32     }
33 
34     MODULEENTRY32 Me32;
35     Me32.dwSize = sizeof(MODULEENTRY32);
36 
37     BOOL bRet = Module32First(hSnap, &Me32);
38     while(bRet)
39     {
40         if (Me32.th32ProcessID == Pid)
41         {
42             printf_s("Have Found!\n");
43             result = Me32.modBaseAddr;    //返回主模塊的基地址
44             break;
45         }
46         bRet = Module32Next(hSnap, &Me32);
47     }
48 
49     CloseHandle(hSnap);
50     return result;
51 }

 

運行效果:debug

 

跳出成功3d

 

總結:code

while(1)在debug編譯下爲mov ecx,1  test ecx, ecx, jz XXXXXXXX ,根據這個就能夠寫入數據了。blog

相關文章
相關標籤/搜索