Visual c++ 使用NtCreateThreadEx API在Win 7 SP 1中进行远程代码注入

Visual c++ 使用NtCreateThreadEx API在Win 7 SP 1中进行远程代码注入,visual-c++,windows-7,code-injection,dll-injection,Visual C++,Windows 7,Code Injection,Dll Injection,我正在尝试学习如何使用NtCreateThreadEx将代码注入正在运行的进程。我在网上找到了一些教程,并尝试了下面所示的代码,它基本上是尝试将一段代码注入运行的notepad.exe。代码注入notepad.exe成功;但是,该程序在注入后(即调用funNtCreateThreadEx后)立即崩溃,抛出以下错误: Run-Time Check Failure #2 - Stack around the variable 'temp2' was corrupted. 有人能帮我解释一下为什么会

我正在尝试学习如何使用NtCreateThreadEx将代码注入正在运行的进程。我在网上找到了一些教程,并尝试了下面所示的代码,它基本上是尝试将一段代码注入运行的notepad.exe。代码注入notepad.exe成功;但是,该程序在注入后(即调用funNtCreateThreadEx后)立即崩溃,抛出以下错误:

Run-Time Check Failure #2 - Stack around the variable 'temp2' was corrupted.
有人能帮我解释一下为什么会出现这个错误吗?我试着用谷歌搜索这个错误,发现它与内存溢出有关。但是,我在下面的代码中没有看到任何内存溢出。请告诉我上述错误的原因。非常感谢您抽出时间

HANDLE NtCreateThreadEx(HANDLE process, LPTHREAD_START_ROUTINE Start, LPVOID lpParameter);

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 DWORD StackZeroBits,
    IN DWORD SizeOfStackCommit,
    IN DWORD SizeOfStackReserve,
    OUT LPVOID lpBytesBuffer
    );

struct NtCreateThreadExBuffer
{
    ULONG Size;
    ULONG Unknown1;
    ULONG Unknown2;
    PULONG Unknown3;
    ULONG Unknown4;
    ULONG Unknown5;
    ULONG Unknown6;
    PULONG Unknown7;
    ULONG Unknown8;
};


HANDLE NtCreateThreadEx(HANDLE process, LPTHREAD_START_ROUTINE Start, LPVOID lpParameter) {

    HMODULE modNtDll = LoadLibrary(L"ntdll.dll");

    if (!modNtDll) {
        std::cout << "Error loading ntdll.dll" << std::endl;
        return 0;
    }

    LPFUN_NtCreateThreadEx funNtCreateThreadEx = (LPFUN_NtCreateThreadEx)GetProcAddress(modNtDll, "NtCreateThreadEx");

    if (!funNtCreateThreadEx) {
        std::cout << "Error loading NtCreateThreadEx()" << std::endl;
        return 0;
    }
    NtCreateThreadExBuffer ntbuffer;

    memset(&ntbuffer, 0, sizeof(NtCreateThreadExBuffer));
    DWORD temp1 = 0;
    DWORD temp2 = 0;


    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;

    HANDLE hThread;
    NTSTATUS status = funNtCreateThreadEx(
        &hThread,
        0x1FFFFF,
        NULL,
        process,
        (LPTHREAD_START_ROUTINE)Start,
        lpParameter,
        FALSE, //start instantly
        0, //null
        0, //null
        0, //null
        &ntbuffer
        );
    return hThread;
}

int main()
{
    int res = -1;
    res = privileges(); //get all required privileges

    DWORD pid = getPid(L"notepad.exe");

    if (pid == 0)
        return PROCESS_NOT_FOUND; //error

    HANDLE p;
    p = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
    if (p == NULL) return OPEN_PROCESS_FAILED; //error


    char * mytext = "Hello by CodeCave!";
    char * mycaption = "Injection result";

    PARAMETERS data;   //let's fill in a PARAMETERS struct
    HMODULE user32 = LoadLibrary(L"User32.dll");
    data.MessageBoxInj = (DWORD)GetProcAddress(user32, "MessageBoxA");
    strcpy_s(data.text, mytext);
    strcpy_s(data.caption, mycaption);
    data.buttons = MB_OKCANCEL | MB_ICONQUESTION;

    //Writing funtion to notepad memory
    DWORD size_myFunc = 0x8000; //Creating more memory than required
    LPVOID MyFuncAddress = VirtualAllocEx(p, NULL, size_myFunc, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    WriteProcessMemory(p, MyFuncAddress, (void*)myFunc, 0x1000, NULL);

    //Parameters to the function to notepad's memory
    LPVOID DataAddress = VirtualAllocEx(p, NULL, sizeof(PARAMETERS), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
    WriteProcessMemory(p, DataAddress, &data, sizeof(PARAMETERS), NULL);

    //invokes injected function
    HANDLE thread = NtCreateThreadEx(p, (LPTHREAD_START_ROUTINE)MyFuncAddress, DataAddress);

    if (thread != 0) {
        //injection completed, not we can wait it to end and free the memory  

    }
    return 0;
}

static DWORD myFunc(PARAMETERS * myparam) {
MsgBoxParam MsgBox = (MsgBoxParam)myparam->MessageBoxInj;
int result = MsgBox(0, myparam->text, myparam->caption, myparam->buttons);
switch (result) {
case IDOK:
    //your code         
    break;
case IDCANCEL:
    //your code
    break;
}
return 0;
} 

int privileges() {
    HANDLE Token;
    TOKEN_PRIVILEGES tp;
    if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &Token))
    {
        LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);
        tp.PrivilegeCount = 1;
        tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
        if (AdjustTokenPrivileges(Token, 0, &tp, sizeof(tp), NULL, NULL) == 0) {
            return 1; //FAIL
        }
        else {
            return 0; //SUCCESS
        }
    }
    return 1;
}

typedef int (WINAPI* MsgBoxParam)(HWND, LPCSTR, LPCSTR, UINT);

struct PARAMETERS {
    DWORD MessageBoxInj;
    char text[50];
    char caption[25];
    int buttons;
};

DWORD myFunc(PARAMETERS * myparam);
HANDLE NtCreateThreadEx(句柄进程,LPTHREAD\u START\u例程启动,LPVOID lpParameter);
typedef NTSTATUS(WINAPI*LPFUN\u NtCreateThreadEx)
(
出了幻影hThread,
在ACCESS_MASK DesiredAccess中,
在LPVOID ObjectAttributes中,
在handleprocesshandle中,
在LPTHREAD\u START\u例程lpStartAddress中,
在LPVOID lpParameter中,
在布尔,
在DWORD STACKZERO BITS中,
在DWORD SizeOfStackCommit中,
在DWORD SizeOfStackReserve,
输出LPVOID lpBytesBuffer
);
结构NtCreateThreadExBuffer
{
乌龙大小;
ULONG未知1;
ULONG未知2;
普隆未知3;
ULONG未知4;
ULONG未知5;
ULONG未知6;
普隆未知7;
ULONG未知8;
};
句柄NtCreateThreadEx(句柄进程,LPTHREAD\u START\u例程启动,LPVOID lpParameter){
HMODULE modNtDll=LoadLibrary(L“ntdll.dll”);
如果(!modNtDll){
std::cout按钮);
开关(结果){
案例IDOK:
//你的代码
打破
案例ID取消:
//你的代码
打破
}
返回0;
} 
int特权(){
处理令牌;
令牌特权;
if(OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,&TOKEN))
{
LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&tp.Privileges[0].Luid);
tp.privilegecont=1;
tp.Privileges[0]。Attributes=SE_PRIVILEGE_ENABLED;
if(AdjustTokenPrivileges(令牌,0,&tp,sizeof(tp),NULL,NULL)==0){
返回1;//失败
}
否则{
返回0;//成功
}
}
返回1;
}
typedef int(WINAPI*MsgBoxParam)(HWND、LPCSTR、LPCSTR、UINT);
结构参数{
dwordmessageboxinj;
字符文本[50];
字符标题[25];
int按钮;
};
DWORD myFunc(参数*myparam);

您使用未记录的NtCreateThreadEx而不是记录的CreateRemoteThread有什么原因吗?(关于崩溃原因的最佳猜测是:NtCreateThreadExBuffer的结构或NtCreateThreadEx的签名已更改,可能是因为您使用的信息用于32位系统,而您运行的是64位系统。)您使用未记录的NtCreateThreadEx而不是记录的CreateRemoteThread有什么原因吗?(关于崩溃原因的最佳猜测是:NtCreateThreadExBuffer的结构或NtCreateThreadEx的签名已更改,可能是因为您使用的信息是针对32位系统的,而您运行的是64位系统。)