題目:編寫一個程序(好比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