使用GetFullPathNameA进行Dll注入不起作用?

时间:2015-02-25 01:30:45

标签: c++ dll

如果我明确地写了地址,那么dll注入工作

char s[1000]="E:\\worldisnotenough.dll"; //Works

如果我使用GetFullPathNameA DLL注入不起作用,并且它们不会给出任何运行时或编译时错误。我查了一下:

char s[1000];
int ax =GetFullPathNameA("worldisnotenough.dll",
                  1000,
                  s, //Output to save the full DLL path
                  NULL);

  std::cout<<s;  //prints the correct path. Working.

cout << s打印正确的路径,但DLL注入不会发生。没有错误发生。我检查了VirtualAllocEx,WriteProcessMemory和CreateRemoteThread,所有这些都正常工作。

编辑:完整代码

#include <QCoreApplication>
#include<windows.h>
#include<tchar.h>
#include<iostream>
#include "E:/Users/Gen/qt project freiza/FreizaLibrary/freizalibrary.h"
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
//    FreizaLibrary lib;
//    QTextStream s(stdin);
//    QString value = s.readLine();

//    lib.injection(value.toInt());
int procID = 13044;

  HANDLE  hHandle = OpenProcess( PROCESS_CREATE_THREAD |
                           PROCESS_QUERY_INFORMATION |
                           PROCESS_VM_OPERATION |
                           PROCESS_VM_WRITE |
                           PROCESS_VM_READ,
                           FALSE,
                           procID );

  QString dllName = "worldisnotenough.dll";

  QFile myDllFile(dllName);
  QFileInfo dllInfo(dllName);
  QString str =dllInfo.absoluteFilePath();
  char s[]="E:\\Users\\Gen\\qt project freiza\\build-libtester-FreizaKit-Release\\release\\worldisnotenough.dll";
std::cout<<strlen(s)<<"\n";
  int ax =GetFullPathNameA("worldisnotenough.dll",
                  86,   //I set it to 1000 before posting this question.
                  s, //Output to save the full DLL path
                  NULL);
//qDebug()<< QString::fromUtf8(s) <<" "<< ax;
  std::cout<<s<<"size "<<ax;
  LPVOID dllPathAddr = VirtualAllocEx(hHandle,
                               0,
                               strlen(s),
                               MEM_RESERVE|MEM_COMMIT,
                               PAGE_EXECUTE_READWRITE);

std::cout<<" test \n";
std::cout<<(int*)dllPathAddr<<endl;
if(dllPathAddr==NULL)
{
    qDebug()<<"virtual failed";
}

size_t x;
 int n= WriteProcessMemory(hHandle,
                     dllPathAddr,
                     s,
                     strlen(s),
                     &x);

  if(n==0)
  {
      qDebug()<<"write failed";
  }
  std::cout<<endl<<n<<"\t"<<x;

  LPVOID addr = (LPVOID)GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryA");
  if(addr==NULL)
  {
      qDebug()<<"get proc failed";
  }

  HANDLE rThread = CreateRemoteThread(hHandle, NULL, 0, (LPTHREAD_START_ROUTINE)addr,dllPathAddr, 0, NULL);
  if(rThread==NULL)
  {
      qDebug()<<"create remote failed";
  }
  WaitForSingleObject(rThread, INFINITE);
  VirtualFreeEx(hHandle, dllPathAddr, 0, MEM_RELEASE);
CloseHandle(hHandle);
  qDebug()<< "done";
    return a.exec();
}

为什么负面投票? 当我发布完整代码。人们说只发布不起作用的代码段。 我最充分地解释了这种情况。由于这些负面投票,我现在无法在stackoverflow上提出问题。谢谢。

2 个答案:

答案 0 :(得分:1)

你需要使用

 strlen(s)+1 

因为它返回字符串的长度而不包括终止空字符本身!因此,VirtualAllocEx和WriteProcessMemory不会写'\ 0'字符,文件名将在内存中的“随机”位置终止。

另外

 char s[]="E:\\Users\\Gen\\qt project freiza\\build-libtester-FreizaKit-Release\\release\\worldisnotenough.dll"; //- Length: 93+1

 int ax =GetFullPathNameA("worldisnotenough.dll",
              sizeof(s), //<-- old: 86 but s[] is 93 + 1 if this has to hold the total path may it was to small?
              s, //Output to save the full DLL path
              NULL);

看起来很棒?!

答案 1 :(得分:1)

您的问题是您正在尝试使用静态定义的字符数组作为GetFullPathNameA的缓冲区!

见这里:

    char s[]="E:\\Users\\Gen\\qt project freiza\\build-libtester-FreizaKit-Release\\release\\worldisnotenough.dll";
std::cout<<strlen(s)<<"\n";
  int ax =GetFullPathNameA("worldisnotenough.dll",
                  86,   //1000 is no good, MAX_PATH is 260
                  s, //Using 's' as a buffer? Don't do that please!
                  NULL);

此外,当使用由'A'表示的ANSI版本时,最大路径长度为260个字符是最大值。 MAX_PATH == 260

“在此函数的ANSI版本中,名称仅限于MAX_PATH字符。要将此限制扩展为32,767个宽字符,请调用该函数的Unicode版本并添加”\?\“”

固定代码:(但是我不使用QT,因此从这里丢失,不应该重要,因为它没有用于注入工作所需的任何东西)

#include <windows.h>
#include <iostream>
#include <tlhelp32.h>

HANDLE GetProcessHandle(wchar_t *ProcessName,ULONG *ReturnedProcessId);

int main(int argc, char *argv[])
{
    ULONG procID;
    HANDLE hHandle=GetProcessHandle(L"ExeToInjectInto.exe",&procID);

    /*HANDLE hHandle=OpenProcess(PROCESS_CREATE_THREAD|PROCESS_QUERY_INFORMATION|PROCESS_VM_OPERATION|
                               PROCESS_VM_WRITE|PROCESS_VM_READ,FALSE,procID);*/

    std::cout<<"handle: "<<hHandle<<" process ID: "<<procID<<"\n";

    char s[]="C:\\Users\\DBVM_OS\\CodeBlocksProjects\\HelpFreizaProject\\bin\\Debug\\mytestdll.dll";
    std::cout<<s<<"\n"<<strlen(s)<<"\n";

    //First Problem:
    /*In the ANSI version of this function, the name is limited to MAX_PATH characters.
     To extend this limit to 32,767 wide characters, call the Unicode version of the function and prepend "\\?\"
    */
    //Second Problem:
    /* Don't use a defined static char[] as a buffer! allocate some memory or use the stack */
    //char s2[MAX_PATH];
    //int ax=GetFullPathNameA("mytestdll.dll",MAX_PATH,s2,0);

    char *s2=new char[MAX_PATH];
    if(s2==0) return 0;
    int ax=GetFullPathNameA("mytestdll.dll",MAX_PATH,s2,0);

    std::cout<<s2<<"\nsize returned: "<<ax<<" strlen: "<<strlen(s2)<<"\n";

    LPVOID dllPathAddr=VirtualAllocEx(hHandle,0,(strlen(s2)+1),MEM_COMMIT,PAGE_EXECUTE_READWRITE);

    std::cout<<"Remotely Allocated String Address: \n";
    std::cout<<(int*)dllPathAddr<<"\n";

    if(dllPathAddr==0)
    {
        OutputDebugStringA("VirtualAllocEx failed...");
        return 0;
    }

    SIZE_T x;
    BOOL n=WriteProcessMemory(hHandle,dllPathAddr,s2,(strlen(s2)+1),&x);
    if(n==FALSE)
    {
        OutputDebugStringA("write failed");
        VirtualFreeEx(hHandle,dllPathAddr,0,MEM_RELEASE);
        CloseHandle(hHandle);
        return 0;
    }

    std::cout<<"WriteProcessMemory Success: "<<n<<", Bytes Written: "<<x<<"\n";

    LPVOID addr=(LPVOID)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "LoadLibraryA");
    if(addr==0)
    {
        OutputDebugStringA("get proc failed");
        VirtualFreeEx(hHandle,dllPathAddr,0,MEM_RELEASE);
        CloseHandle(hHandle);
        return 0;
    }

    std::cout<<"LoadLibraryA: "<<addr<<"\n";

    HANDLE rThread=CreateRemoteThread(hHandle,0,0,(LPTHREAD_START_ROUTINE)addr,dllPathAddr,0,0);
    if(rThread==0)
    {
        OutputDebugStringA("create remote failed");
        VirtualFreeEx(hHandle,dllPathAddr,0,MEM_RELEASE);
        CloseHandle(hHandle);
        return 0;
    }


    WaitForSingleObject(rThread,INFINITE);
    std::cout<<"DLL Should have been injected successfully at this point...\nFreeing remote string";

    BOOL freed=VirtualFreeEx(hHandle,dllPathAddr,0,MEM_RELEASE);
    if(freed==0) OutputDebugStringA("Freeing Remote String Failed...");

    delete[] s2; //if you dynamically allocated s2 like I've done...
    CloseHandle(hHandle);
    return 0;
}

HANDLE GetProcessHandle(wchar_t *ProcessName,ULONG *ReturnedProcessId)
{
    PROCESSENTRY32W pe;
    HANDLE Snap;

    ZeroMemory(&pe, sizeof(PROCESSENTRY32W));
    pe.dwSize=sizeof(PROCESSENTRY32W);
    Snap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);

    if(Snap==INVALID_HANDLE_VALUE) return 0;

    BOOL bProcess=Process32FirstW(Snap,&pe);
    while(bProcess)
    {
        if(_wcsicmp(pe.szExeFile,ProcessName)==0)
        {
            HANDLE ProcessHandle=OpenProcess(PROCESS_CREATE_THREAD|PROCESS_QUERY_INFORMATION|PROCESS_VM_OPERATION|
                               PROCESS_VM_WRITE|PROCESS_VM_READ,FALSE,pe.th32ProcessID);

            if(ReturnedProcessId!=0)
                *ReturnedProcessId=pe.th32ProcessID;

            CloseHandle(Snap);
            return ProcessHandle;
        }

        bProcess=Process32NextW(Snap, &pe);
    }
    if(ReturnedProcessId!=0) *ReturnedProcessId=0;
    CloseHandle(Snap);
    return 0;
}