[英]Failing dll injection
我正在為我的網絡制作一個安全程序。 它的實例之一是檢查和監控調用了哪些 api 和庫。 執行此操作的 dll 以及與之相關的程序已經完成。 但是有一個我似乎無法解決的問題。
當嘗試使用NtCreateThreadEx
將我的 dll 注入系統進程(例如 explorer.exe,我的主要測試系統進程)時,我得到返回值:C0000022,這意味着類似以下內容:Status_Access_Denied(它返回 NTSTATUS,但 DWORD 將做)
我不知道該怎么辦,我以管理員身份運行,我提高了權限並使用了正確的功能,但我仍然得到 c0000022
這是我用來注入的代碼
#include "main.h"
typedef DWORD NTSTATUS;
struct NtCreateThreadExBuffer{
ULONG Size;
ULONG Unknown1;
ULONG Unknown2;
PULONG Unknown3;
ULONG Unknown4;
ULONG Unknown5;
ULONG Unknown6;
PULONG Unknown7;
ULONG Unknown8;
};
typedef NTSTATUS (WINAPI *LPFUN_NtCreateThreadEx)
(
OUT PHANDLE hThread,
IN ACCESS_MASK DesiredAccess,
IN LPVOID ObjectAttributes,
IN HANDLE ProcessHandle,
IN LPTHREAD_START_ROUTINE lpStartAddress,
IN LPVOID lpParameter,
IN BOOL CreateSuspended,
IN ULONG StackZeroBits,
IN ULONG SizeOfStackCommit,
IN ULONG SizeOfStackReserve,
OUT LPVOID lpBytesBuffer
);
using namespace std;
//#define CREATE_THREAD_ACCESS (PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ)
#define CREATE_THREAD_ACCESS ( PROCESS_ALL_ACCESS )
BOOL LoadDll(char *procName, char *dllName);
BOOL InjectDLL(DWORD dwProcessID, char *dllName);
BOOL LoadDll(char *dllName, DWORD dwProcID){
printf("Process Id to Inject: %d",dwProcID);
if(!dwProcID){
printf("No vailid PID\n");
return false;
}
FILE* FileCheck = fopen(dllName, "r");
if(FileCheck==NULL){
printf("\nUnable to inject %s", dllName);
return false;
}
fclose(FileCheck);
if(!InjectDLL(dwProcID, dllName)){
printf("injection failed\n");
return false;
} else {
return true;
}
}
BOOL InjectDLL(DWORD dwProcessID, char *dllName){
HANDLE hProc;
HANDLE hToken;
char buf[50]={0};
LPVOID RemoteString, LoadLibAddy;
if(!dwProcessID)return false;
HANDLE hCurrentProc = GetCurrentProcess();
if (!OpenProcessToken(hCurrentProc,TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,&hToken)){
printf("OpenProcessToken Error:%d\n", GetLastError());
} else {
if (!RaisePrivleges(hToken, (char*)SE_DEBUG_NAME)){
printf("SetPrivleges SE_DEBUG_NAME Error:%d\n", GetLastError());
}
}
if (hToken)CloseHandle(hToken);
hProc = OpenProcess(CREATE_THREAD_ACCESS, FALSE, dwProcessID);
printf("\nHandle to process: %x\n", hProc);
if(!hProc){
printf("OpenProcess() failed: %d", GetLastError());
return false;
}
LoadLibAddy = (LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
if(!LoadLibAddy){
printf("GetProcAddress() failed: %d", GetLastError());
return false;
}
RemoteString = (LPVOID)VirtualAllocEx(hProc, NULL, strlen(dllName), MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
if(RemoteString == NULL){
printf("VirtualAllocEx() failed: %d", GetLastError());
return false;
}
printf("\nRemote address: %x\n", RemoteString);
if(WriteProcessMemory(hProc, (LPVOID)RemoteString, dllName, strlen(dllName), NULL) == NULL){
printf("WriteProcessMemory() failed: %d", GetLastError());
return false;
}
/*
if(!CreateRemoteThread(hProc, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibAddy, (LPVOID)RemoteString, NULL, NULL)){
printf("CreateRemoteThread() failed: %d", GetLastError());
return false;
}
*/
HMODULE modNtDll = GetModuleHandle("ntdll.dll");
if( !modNtDll )
{
printf("n failed to get module handle for ntdll.dll, Error=0x%.8x", GetLastError());
return 0;
}
LPFUN_NtCreateThreadEx funNtCreateThreadEx =
(LPFUN_NtCreateThreadEx) GetProcAddress(modNtDll, "NtCreateThreadEx");
if( !funNtCreateThreadEx )
{
printf("n failed to get function (NTCreateThreadEx) address from ntdll.dll, Error=0x%.8x\nTrying CreateRemoteThread api\n", GetLastError());
if(!CreateRemoteThread(hProc, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibAddy, (LPVOID)RemoteString, NULL, NULL)){
printf("CreateRemoteThread() failed: %d", GetLastError());
return false;
} else {
printf("CreateRemoteThread success!\n");
return true;
}
return 0;
}
NtCreateThreadExBuffer ntbuffer;
memset (&ntbuffer,0,sizeof(NtCreateThreadExBuffer));
DWORD temp1 = 0;
DWORD temp2 = 0;
HANDLE pRemoteThread = NULL;
ntbuffer.Size = sizeof(NtCreateThreadExBuffer);
ntbuffer.Unknown1 = 0x10003;
ntbuffer.Unknown2 = 0x8;
ntbuffer.Unknown3 = &temp2;
ntbuffer.Unknown4 = 0;
ntbuffer.Unknown5 = 0x10004;
ntbuffer.Unknown6 = 4;
ntbuffer.Unknown7 = &temp1;
ntbuffer.Unknown8 = 0;
NTSTATUS status = funNtCreateThreadEx(
&pRemoteThread,
0x1FFFFF,
NULL,
hProc,
(LPTHREAD_START_ROUTINE) LoadLibAddy,
(LPVOID)RemoteString,
FALSE, //start instantly
NULL,
NULL,
NULL,
&ntbuffer
);
printf("NTCreateThreadEx return: %x\n", status);
// Resume the thread execution
WaitForSingleObject(pRemoteThread, INFINITE);
//Check the return code from remote thread function
DWORD dwExitCode;
if( GetExitCodeThread(pRemoteThread, (DWORD*) &dwExitCode) )
{
printf("\n Remote thread returned with status = %d\n", dwExitCode);
}
CloseHandle(pRemoteThread);
CloseHandle(hProc);
return true;
}
BOOL RaisePrivleges( HANDLE hToken, char *pPriv ){
TOKEN_PRIVILEGES tkp;
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
tkp.Privileges[0].Luid.HighPart = 0;
tkp.Privileges[0].Luid.LowPart = 0;
if (!LookupPrivilegeValue(NULL, pPriv, &tkp.Privileges[0].Luid)){
printf("LookupPrivilegeValue Error:%d\n", GetLastError());
return FALSE;
}
int iRet = AdjustTokenPrivileges(hToken, FALSE, &tkp, 0x10, (PTOKEN_PRIVILEGES)NULL, 0);
if (iRet == NULL){
printf( "AdjustTokenPrivileges Error:%d\n", GetLastError());
return TRUE;
} else {
iRet = GetLastError();
switch (iRet){
case ERROR_NOT_ALL_ASSIGNED:
printf("AdjustTokenPrivileges ERROR_NOT_ALL_ASSIGNED\n" );
return FALSE;
case ERROR_SUCCESS:
return TRUE;
default:
printf("AdjustTokenPrivileges Unknow Error:%d\n", iRet);
return FALSE;
}
}
}
由於很難找到此問題的正確答案,因此即使該線程很舊,我還是要發帖。 我試圖在 Win7 x64 上注入 x64 服務並不斷遇到同樣的問題。 我的解決方案是:
1) 如果您在 VISTA 或更高版本上運行,那么您可能試圖從“非受保護進程”注入“受保護進程”。 請參閱 MSDN 中的進程安全和訪問權限。 非受保護進程不能在受保護進程中創建線程; 盡管我必須承認,當您請求不適當的訪問權限而不是隨后的創建線程調用失敗時,我希望對 open 進程的調用會失敗。
2) 為什么你使用NtCreateThreadEx()
而不是簡單地調用CreateRemoteThread()
?
3)這可能不是您的問題的原因,但是...您未能為字符串中的空終止符分配內存,您應該分配strlen(dllName) + 1
。
4)我假設正在進行注入的進程和您正在注入的進程都是相同的架構,您沒有在 x64 上運行 x86 exe 並期望注入 x64 exe?
您必須指定注入的 DLL 的完整路徑,否則將找不到。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.