积极答复者
关于部分WIN7远程线程注入失败的问题

问题
-
同样一份代码,在XP完全没问题,而在部分WIN7的客户端无法注入,而一部分又没问题~~
注入部分,代码如下:
#include <afx.h>
#include "InjectDllWin7.h"
#pragma warning(disable:4089)
BOOL __stdcall IsVistaOrLater()
{
OSVERSIONINFO osvi;
ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if(!GetVersionEx(&osvi))
return FALSE;
if(osvi.dwMajorVersion >= 6)
return TRUE;
return FALSE;
}
DWORD __stdcall GetDebugPrivilege()
{
CString strMsg;
HANDLE hToken;
DWORD Ret=1;
TOKEN_PRIVILEGES TP;
if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
{
strMsg.Format(_T("[-] Error in GetDebugPrivilege OpenProcessToken: %u\n"), GetLastError());
MessageBox(NULL,strMsg,NULL,MB_OK);
TRACE(strMsg);
Ret = 0;
goto bye;
}
if(!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &TP.Privileges[0].Luid))
{
strMsg.Format(_T("[-] Error in GetDebugPrivilege LookupPrivilegeValue: %u\n"), GetLastError());
MessageBox(NULL,strMsg,NULL,MB_OK);
TRACE(strMsg);
Ret = 0;
goto bye;
}
TP.PrivilegeCount=1;
TP.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
if(!AdjustTokenPrivileges(hToken,
FALSE,
&TP,
0,
NULL,
NULL))
{
strMsg.Format(_T("[-] Error in GetDebugPrivilege with AdjustTokenPrivileges: %u\n"), GetLastError());
MessageBox(NULL,strMsg,NULL,MB_OK);
TRACE(strMsg);
Ret = 0;
goto bye;
}
bye:
CloseHandle(hToken);
return Ret;
}
/*
kernelbase.dll
7597BD24 6A 0C PUSH 0C
7597BD26 68 01000100 PUSH 10001
7597BD2B 53 PUSH EBX
7597BD2C 8D85 F0FDFFFF LEA EAX, DWORD PTR SS:[EBP-210]
7597BD32 50 PUSH EAX
7597BD33 FF15 00129775 CALL NEAR DWORD PTR DS:[<&ntdll.CsrClientCallServer>] ; ntdll.CsrClientCallServer
7597BD39 8B85 10FEFFFF MOV EAX, DWORD PTR SS:[EBP-1F0]
7597BD3F 8985 E8FDFFFF MOV DWORD PTR SS:[EBP-218], EAX
7597BD45 399D E8FDFFFF CMP DWORD PTR SS:[EBP-218], EBX
7597BD4B 0F8C 13D80100 JL KERNELBA.75999564
*/
DWORD __stdcall MyCsrClientCallServer(PVOID Arg1, PVOID Arg2, DWORD Arg3, DWORD Arg4)
{
*(PDWORD)((PBYTE)Arg1+0x20)=0;
return 0;
}
DWORD __stdcall ScanIatForImportAddress(HANDLE hModule, PCHAR Import)
{
PIMAGE_DOS_HEADER DosHeader;
PIMAGE_NT_HEADERS NtHeader;
PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor;
PIMAGE_THUNK_DATA OriginalThunk;
PDWORD FirstThunk;
PIMAGE_IMPORT_BY_NAME ImportByName;
PCHAR Name;
DWORD i;
if(hModule == NULL || Import == NULL)
return 0;
DosHeader = (PIMAGE_DOS_HEADER)hModule;
NtHeader = (PIMAGE_NT_HEADERS)((PBYTE)hModule+DosHeader->e_lfanew);
ImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)((PBYTE)hModule+NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
while(*(PDWORD)ImportDescriptor!=0)
{
//printf("[*] Module : %s\n", ((PBYTE)hModule+ImportDescriptor->Name));
OriginalThunk=(PIMAGE_THUNK_DATA)((PBYTE)hModule+ImportDescriptor->OriginalFirstThunk);
FirstThunk=(PDWORD)((PBYTE)hModule+ImportDescriptor->FirstThunk);
i=0;
while(*(PDWORD)OriginalThunk!=0)
{
ImportByName=(PIMAGE_IMPORT_BY_NAME)((PBYTE)hModule+OriginalThunk->u1.AddressOfData);
Name=(PCHAR)((PBYTE)ImportByName+sizeof(WORD));
//printf("[*] ImportName(%u): %s\n", ImportByName->Hint, Name);
if(_stricmp(Name, Import)==0)
return (DWORD)&FirstThunk[i++];
OriginalThunk++;
i++;
}
ImportDescriptor++;
}
return 0;
}
HANDLE WINAPI MyCreateRemoteThread(HANDLE hProcess,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
SIZE_T dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId)
{
HANDLE hThread;
DWORD ImportAddress, OriginalCsrClientCallServer, OldProtect;
CString strMsg;
ImportAddress = ScanIatForImportAddress(GetModuleHandleA("kernelbase.dll"), "CsrClientCallServer");
if(ImportAddress == 0)
{
strMsg.Format(_T("[-] Error in MyCreateRemoteThread with ScanIatForThunk : Cannot find thunk address\n"));
MessageBox(NULL,strMsg,NULL,MB_OK);
TRACE(strMsg);
return NULL;
}
printf("[*] CsrClientCallServer import address at : 0x%x\n", ImportAddress);
VirtualProtect((PVOID)ImportAddress, sizeof(DWORD), PAGE_EXECUTE_READWRITE, &OldProtect);
OriginalCsrClientCallServer = *(PDWORD)ImportAddress;
*(PDWORD)ImportAddress = (DWORD)MyCsrClientCallServer;
hThread = CreateRemoteThread(hProcess, lpThreadAttributes, dwStackSize, lpStartAddress, lpParameter, dwCreationFlags, lpThreadId);
if(hThread == NULL)
{
strMsg.Format(_T("[-] Error in MyCreateRemoteThread with CreateRemoteThread : %u\n"), GetLastError());
MessageBox(NULL,strMsg,NULL,MB_OK);
TRACE(strMsg);
return NULL;
}
TRACE(_T("End to call CreateRemoteThread , bye...\n"));
*(PDWORD)ImportAddress = OriginalCsrClientCallServer;
VirtualProtect((PVOID)ImportAddress, sizeof(DWORD), OldProtect, &OldProtect);
return hThread;
}
BOOL __stdcall InjectDllWin7(DWORD Pid, LPTSTR DllName)
{
CString strMsg;
CHAR FullDllPath[MAX_PATH] = {0};
DWORD ThreadID;
HANDLE hThread;
HANDLE hProcess;
DWORD InjectSize;
LPVOID Arg;
LPTHREAD_START_ROUTINE Injector;
if(!IsVistaOrLater())
{
MessageBox(NULL,_T("[*] Current system isn't Win7 or later !"),_T("HappyHeros.com"),MB_OK | MB_ICONQUESTION);
return FALSE;
}
TRACE(_T("[*] Inject dll starting !\n"));
RtlZeroMemory(FullDllPath, sizeof(FullDllPath));
GetCurrentDirectoryA(sizeof(FullDllPath)-sizeof(CHAR), FullDllPath);
_tcscat(FullDllPath, "\\");
_tcscat(FullDllPath, DllName);
strMsg.Format(_T("[*] FullDllPath : %s\n"), FullDllPath);
TRACE(strMsg);
TRACE(_T("[*] start to call GetDebugPrivilege function...\n"));
if(!GetDebugPrivilege())
{
strMsg.Format(_T("[-] Error in InjectDll with GetDebugPrivilege : Cannot grant SeDebugPrivilege\n"));
MessageBox(NULL,strMsg,NULL,MB_OK);
TRACE(strMsg);
return FALSE;
}
TRACE(_T("[*] start to call OpenProcess function...\n"));
hProcess = OpenProcess(PROCESS_VM_OPERATION|PROCESS_VM_WRITE|PROCESS_VM_READ|PROCESS_CREATE_THREAD|PROCESS_QUERY_INFORMATION, FALSE, Pid);
if(hProcess == NULL)
{
strMsg.Format(_T("[-] Error in InjectDll with OpenProcess : %u\n"), GetLastError());
MessageBox(NULL,strMsg,NULL,MB_OK);
TRACE(strMsg);
return FALSE;
}
InjectSize = strlen(FullDllPath)+1;
TRACE(_T("[*] start to call VirtualAllocEx function...\n"));
Arg = VirtualAllocEx(hProcess, NULL, InjectSize, MEM_COMMIT, PAGE_READWRITE);
if(Arg == NULL)
{
strMsg.Format(_T("[-] Error in InjectDll with VirtualAllocEx : %u\n"), GetLastError());
MessageBox(NULL,strMsg,NULL,MB_OK);
TRACE(strMsg);
CloseHandle(hProcess);
return FALSE;
}
TRACE(_T("[*] start to call WriteProcessMemory function...\n"));
if(WriteProcessMemory(hProcess, Arg, FullDllPath, InjectSize, 0) == FALSE)
{
strMsg.Format(_T("[-] Error in InjectDll with WriteProcessMemory : %u\n"), GetLastError());
MessageBox(NULL,strMsg,NULL,MB_OK);
TRACE(strMsg);
CloseHandle(hProcess);
return FALSE;
}
Injector = (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");
TRACE(_T("[*] tart to call MyCreateRemoteThread function...\n"));
hThread = MyCreateRemoteThread(hProcess, NULL, 0, Injector , Arg, 0, &ThreadID);
if(hThread == NULL)
{
strMsg.Format(_T("[-] Error in InjectDll with MyCreateRemoteThread : %u\n"), GetLastError());
MessageBox(NULL,strMsg,NULL,MB_OK);
TRACE(strMsg);
CloseHandle(hProcess);
return FALSE;
}
TRACE(_T("[*] end to call MyCreateRemoteThread function...\n"));
TRACE(_T("[*] start to call WaitForSingleObject function...\n"));
// 在这里有部分WIN7则挂起始终等待,导致函数没有返回,主线程一直是sumppend状态
if(WaitForSingleObject(hThread, INFINITE) == WAIT_FAILED)
{
strMsg.Format(_T("[-] Error in InjectDll with WaitForSingleObject : %u\n"), GetLastError());
MessageBox(NULL,strMsg,NULL,MB_OK);
TRACE(strMsg);
CloseHandle(hProcess);
CloseHandle(hThread);
return FALSE;
}
TRACE(_T("[*] start to call VirtualFreeEx function...\n"));
if(VirtualFreeEx(hProcess, Arg, 0, MEM_DECOMMIT) == FALSE)
{
strMsg.Format(_T("[-] Error in InjectDll with VirtualFreeEx : %u\n"), GetLastError());
MessageBox(NULL,strMsg,NULL,MB_OK);
TRACE(strMsg);
CloseHandle(hProcess);
CloseHandle(hThread);
return FALSE;
}
TRACE(_T("[*] Inject dll successed !\n"));
CloseHandle(hProcess);
CloseHandle(hThread);
return TRUE;
}
之前是封装在一个DLL中的,主进程动态加载DLL来调用,代码如下:void CInjectDlg::OnStart()
{
// TODO: Add your control notification handler code here
PROCESS_INFORMATION pi;
STARTUPINFO si;
CString strMsg;
CString strExe = _T("");
char szSysPath[MAX_PATH]= {0x00};
char szPath[MAX_PATH];
HINSTANCE handle;
ZeroMemory(&si,sizeof(si));
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_MINIMIZE;
GetWindowsDirectory( szPath, sizeof(szPath) );
strExe.Format(_T("%s\\system32\\notepad.exe"),szPath);
if( !CreateProcess(strExe,NULL,NULL,NULL,FALSE,CREATE_SUSPENDED,NULL,NULL,&si,&pi) )
{
strMsg.Format(_T("启动纪事本失败!错误代码: %d"),GetLastError());
MessageBox(strMsg);
return;
}
handle = LoadLibrary("Test.dll");
if(handle)
{
MyInject = (INJECTWIN7)GetProcAddress(handle,"InjectDllWin7");
if( !MyInject )
{
MessageBox("函数MyInject地址获取失败!");
return;
}
if(!MyInject(pi.dwProcessId,_T("MsgBox.dll")))
{
TerminateProcess(pi.hProcess,0);
}
else
{
ResumeThread(pi.hThread);
MessageBox(_T("启动成功!\r\n\r\n感谢你的友情测试!"));
}
}
FreeLibrary(handle);
}我把注入的代码,放在记事本中测试,部分WIN7成功,部分WIN7则失败,不太明白这个问题所在,希望指点一下,不盛感激!
One Code , One Dream !
- 已编辑 Koma.Walk 2011年8月13日 2:53 modify