none
关于部分WIN7远程线程注入失败的问题 RRS feed

  • 问题

  • 同样一份代码,在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
    2011年8月13日 2:49

答案

  • 首先检查权限问题,然后如果不是权限问题,你需要在你每个调用Windows API的地方加上日志输出检查是不是API都正确返回了
    0xBAADF00D
    • 已标记为答案 Koma.Walk 2011年8月16日 9:02
    2011年8月14日 16:40
    版主

全部回复

  • 首先检查权限问题,然后如果不是权限问题,你需要在你每个调用Windows API的地方加上日志输出检查是不是API都正确返回了
    0xBAADF00D
    • 已标记为答案 Koma.Walk 2011年8月16日 9:02
    2011年8月14日 16:40
    版主
  • 首先检查权限问题,然后如果不是权限问题,你需要在你每个调用Windows API的地方加上日志输出检查是不是API都正确返回了
    0xBAADF00D
    Thanks !

    One Code , One Dream !
    2011年8月15日 3:33
  • also check whether the target process has the same architecture to yours,

    then, check whether you are trying to inject a service process running in Session 0, on windows 7, remote-thread injection does not go across session.

     

    2011年8月18日 6:29