日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

Process-wide API spying - an ultimate hack 摘要翻译(三)

發(fā)布時(shí)間:2024/3/13 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Process-wide API spying - an ultimate hack 摘要翻译(三) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

在已運(yùn)行進(jìn)程注入間諜DLL

主體代碼(文字說(shuō)明放在代碼的注釋中):
void inject(DWORD threadid,BYTE*remotebuff, HMODULE hMod, DWORD
entrypoint,HANDLE processhandle,HANDLE eventhandle);

void loadandinject(DWORD procid)
{
??? BYTE array[256];
??? char buff[1024];
??? DWORD byteswritten,dw,threadid;

??? //按照J(rèn)effrey Richter提出的方法在目標(biāo)進(jìn)程加載spydll.dll
??? HANDLE processhandle=OpenProcess(PROCESS_ALL_ACCESS,0,procid);
??? BYTE* writebuff=(BYTE*)VirtualAllocEx(processhandle,0,4096,MEM_RESERVE,PAGE_EXECUTE_READWRITE);
??? writebuff=(BYTE*)VirtualAllocEx(processhandle,writebuff,4096,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
??? DWORD funcptr=(DWORD)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
??? strcpy(buff,"spydll.dll");
??? WriteProcessMemory(processhandle,writebuff,buff,256,&byteswritten);
??? CreateRemoteThread(processhandle,0,0,(LPTHREAD_START_ROUTINE)funcptr,writebuff,0,&threadid);

??? //在目標(biāo)進(jìn)程中找到spydll.dll的模塊句柄
??? HANDLE snap= CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,procid);
??? MODULEENTRY32 mod;
??? mod.dwSize=sizeof(MODULEENTRY32);
??? Module32First(snap,&mod);
??? HMODULE hMod=0;

??? while(Module32Next(snap,&mod))
??? {
??????? if(!strcmp(mod.szModule,"spydll.dll"))
??????? {
??????????? hMod=mod.hModule;
??????????? break;
??????? }
??? }
??? CloseHandle(snap);

??? //獲取spydll.dll在目標(biāo)進(jìn)程中的入口點(diǎn)
??? ReadProcessMemory(processhandle,(void*)hMod,buff,1024,&dw);
??? IMAGE_DOS_HEADER * dosheader=(IMAGE_DOS_HEADER *)buff;
??? IMAGE_OPTIONAL_HEADER * opthdr =(IMAGE_OPTIONAL_HEADER *)((BYTE*)buff+dosheader->e_lfanew+24);
??? DWORD entry=(DWORD)hMod+opthdr->AddressOfEntryPoint;

??? //創(chuàng)建一個(gè)自我復(fù)位的Event,其初始狀態(tài)為沒(méi)有信號(hào)狀態(tài)
??? HANDLE eventhandle=CreateEvent(0,0,0,"spyevent");

??? //讓目標(biāo)進(jìn)程已經(jīng)運(yùn)行的線程調(diào)用掛鉤DLL文件的入口點(diǎn)函數(shù)
??? snap= CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,0);
??? THREADENTRY32 th;
??? th.dwSize=sizeof(THREADENTRY32);
??? Thread32First(snap,&th);
??? while(Thread32Next(snap,&th))
??? {
??????? if(th.th32OwnerProcessID==procid)
??????????? inject(th.th32ThreadID,writebuff,hMod,entry,processhandle,eventhandle);
??? }

??? CloseHandle(eventhandle);
}

inject和前面篇幅的函數(shù)一樣,也是機(jī)器碼寫(xiě)的。但這里的情況更加復(fù)雜一些,因?yàn)楸仨毟淖兡繕?biāo)線程的執(zhí)行體上下文,讓它調(diào)用我們硬編碼以調(diào)用spydll.dll的入口點(diǎn),以下是它的匯編偽碼:
??? push eax
??? push ebx
??? push ecx
??? push edx
??? pushf
??? push 0
??? push value_of_DLL_THREAD_ATTACH
??? push hMod
??? call dword ptr[_imp_Dllentrypoint]
??? push eventnameptr
??? push 0
??? push value_of_EVENT_ALL_ACCESS
??? call dword ptr[_imp_OpenEvent]
??? push eax
??? push eax
??? call dword ptr[_imp_SetEvent]
??? call dword ptr[_imp_CloseHandle]
??? popf
??? pop edx
??? pop ecx
??? pop ebx
??? pop eax
??? jmp dword ptr[retaddressptr]

inject具體代碼如下:

void inject(DWORD threadid,BYTE* remotebuff,HMODULE hMod,DWORD entrypoint,HANDLE processhandle,HANDLE eventhandle)
{
??? DWORD arg1=(DWORD)hMod,arg2=DLL_THREAD_ATTACH,arg3=0;

??? typedef HANDLE (__stdcall*func)(DWORD,BOOL,DWORD);

??? func OpenThread=(func)GetProcAddress(GetModuleHandle("KERNEL32.dll"),"OpenThread");
??? HANDLE threadhandle=OpenThread(THREAD_SUSPEND_RESUME| THREAD_GET_CONTEXT|THREAD_SET_CONTEXT,0,threadid);
??? SuspendThread(threadhandle);
??? CONTEXT Context;
??? Context.ContextFlags=CONTEXT_CONTROL;
??? GetThreadContext(threadhandle,&Context);

??? DWORD retaddress= Context.Eip;

??? //we are going to do the tough job of filling the array with the machine codes
??? BYTE array[256];

??? //copy all necessary data into the array
??? DWORD *openeventptr=(DWORD *)&array[100];
??? openeventptr[0]=(DWORD )&OpenEvent;
??? openeventptr=(DWORD *)&remotebuff[100];

??? DWORD*seteventptr=(DWORD *)&array[104];
??? seteventptr[0]=(DWORD )&SetEvent;
??? seteventptr=(DWORD *)&remotebuff[104];

??? DWORD* closehandleptr=(DWORD *)&array[108];
??? closehandleptr[0]=(DWORD )&CloseHandle;
??? closehandleptr=(DWORD *)&remotebuff[108];

??? DWORD* entrypointptr=(DWORD *)&array[112];
??? entrypointptr[0]=entrypoint;
??? entrypointptr=(DWORD *)&remotebuff[112];

??? DWORD* retaddressptr=(DWORD *)&array[116];
??? retaddressptr[0]=retaddress;
??? retaddressptr=(DWORD *)&remotebuff[116];

??? strcpy((char*)&array[120],"spyevent");
??? char*eventnameptr=(char*)&remotebuff[120];

??? //now we are filling the array with actual machine instructions

??? //push registers and flags
??? array[0]=0x50;?? //push eax
??? array[1]=0x53;?? //push ebx
??? array[2]=0x51;?? //push ecx
??? array[3]=0x52;?? //push edx
??? array[4]=0x9C;?? //pushf

??? //push entrypoint arguments
??? array[5]=0x68;?? //push 0
??? memmove(&array[6],&arg3,4);
??? array[10]=0x68;? //push value_of_DLL_THREAD_ATTACH
??? memmove(&array[11],&arg2,4);
??? array[15]=0x68;? //push hMod
??? memmove(&array[16],&arg1,4);

??? //call entrypoint
??? array[20]=0xFF;? //call dword ptr[_imp_Dllentrypoint]
??? array[21]=0x15;
??? memmove(&array[22],&entrypointptr,4);

??? //push OpenEvent arguments
??? array[26]=0x68;? //push eventnameptr
??? memmove(&array[27],&eventnameptr,4);
??? array[31]=0x68;? //push 0
??? int a=0;
??? memmove(&array[32],&a,4);
??? array[36]=0x68;? //push value_of_EVENT_ALL_ACCESS
??? a=EVENT_ALL_ACCESS;
??? memmove(&array[37],&a,4);

??? //call OpenEvent
??? array[41]=0xFF;? //call dword ptr[_imp_OpenEvent]
??? array[42]=0x15;
??? memmove(&array[43],&openeventptr,4);
???
??? // push eax
??? array[47]=0x50;
??? // push eax
??? array[48]=0x50;

??? //call SetEvent
??? array[49]=0xFF;
??? array[50]=0x15;
??? memmove(&array[51],&seteventptr,4);

??? //call CloseHandle
??? array[55]=0xFF;
??? array[56]=0x15;
??? memmove(&array[57],&closehandleptr,4);

??? //restore registers and flags
??? array[61]=0x9D;?? //popf
??? array[62]=0x5A;?? //pop edx
??? array[63]=0x59;?? //pop ecx
??? array[64]=0x5B;?? //pop ebx
??? array[65]=0x58;?? //pop eax

??? //jmp dword ptr[retaddressptr]
??? array[66]=0xFF;
??? array[67]=0x25;
??? memmove(&array[68],&retaddressptr,4);

??? // we have finished filling the array, thanks God
??? DWORD byteswritten;
??? WriteProcessMemory(processhandle,(void *)remotebuff,(void*)array,256,&byteswritten);
??? Context.Eip=(DWORD)&remotebuff[0];
??? SetThreadContext(threadhandle,&Context);
??? ResumeThread(threadhandle);

??? //在改變目標(biāo)線程的執(zhí)行體上下文后,inject函數(shù)為等待目標(biāo)線程置位同步的Event,所以直到目標(biāo)線程已經(jīng)恢復(fù)到原來(lái)的執(zhí)行體上下文前,Inject函數(shù)都不能對(duì)其他的線程進(jìn)行更改操作
??? //此外這里使用的同步技術(shù)還可以用于檢測(cè)線程死鎖
??? WaitForSingleObject(eventhandle,INFINITE);

??? CloseHandle(threadhandle);
}

注意:如果我們需要把spydll.dll注入到我們自己創(chuàng)建的進(jìn)程,最好的辦法是在spydll.dll剛被加載的時(shí)候改寫(xiě)目標(biāo)函數(shù)的地址(此時(shí)的fdwReason=DLL_PROCESS_ATTACH),因?yàn)檫@個(gè)時(shí)候我們的進(jìn)程還只有一個(gè)線程(主線程)在運(yùn)行。但如果要把spydll.dll注入到已經(jīng)運(yùn)行的進(jìn)程,就需要在每一個(gè)目標(biāo)線程中調(diào)用spydll.dll的入口函數(shù),以分配函數(shù)替換需要的存貯空間,否則就會(huì)導(dǎo)致調(diào)用Prolog()函數(shù)時(shí)因?yàn)闆](méi)有分配存貯空間而出錯(cuò)。另外一方面,我們要Hook的目標(biāo)函數(shù)的地址將被我們的spydll.dll輸出,所以我們可以通過(guò)spydll.dll的輸出函數(shù)表獲取目標(biāo)函數(shù)在注入進(jìn)程中的地址。

由于對(duì)已運(yùn)行進(jìn)程的注入很復(fù)雜,除了實(shí)驗(yàn)用途以外,建議使用自己創(chuàng)建進(jìn)程的方式來(lái)注入。

總結(jié)

以上是生活随笔為你收集整理的Process-wide API spying - an ultimate hack 摘要翻译(三)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。