Visual c++ 使用NtCreateThreadEx API在Win 7 SP 1中进行远程代码注入
我正在尝试学习如何使用NtCreateThreadEx将代码注入正在运行的进程。我在网上找到了一些教程,并尝试了下面所示的代码,它基本上是尝试将一段代码注入运行的notepad.exe。代码注入notepad.exe成功;但是,该程序在注入后(即调用funNtCreateThreadEx后)立即崩溃,抛出以下错误: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. 有人能帮我解释一下为什么会
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位系统。)