【发布时间】:2014-04-22 05:46:13
【问题描述】:
好的,我正在学习 Windows API 以及如何创建线程/进程和获得调试权限等。非常新,如果这是一个愚蠢的问题,我深表歉意。
无论如何,我正在创建一个 .dll 注入器来使用,并且通过注入我的 .dll 文件成功地注入了 32 位和 64 位进程,包括 explorer.exe。但是,我正在尝试在标准用户模式下对此进行测试,但在弄清楚如何操作时遇到了问题。
现在我正在为 .dll 和 injector.exe 编译为 x64。我正在尝试注入 x64 进程,主要是 explorer.exe(在管理员上工作)。使用 Visual Studio 2012,进行了一些优化,没有清单,没有调试(仅在需要时)。 操作系统= Win 7 x64
另外,我尝试从多个位置访问 .dll,E:\ 驱动器只是我 HD 上的另一个分区。
- 究竟为什么会发生这种情况?
- 有什么方法可以绕过它? (如有可能,请提供参考、解释、示例)
NtCreateThreadEx();调用返回一个为 0 的线程。因此它没有正确加载。
#include <windows.h>
#include <iostream>
#include <stdlib.h>
#include <tlhelp32.h>
#define CREATE_THREAD_ACCESS (PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ)
using namespace std;
DWORD getPid(string procName);
int privileges();
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING;
typedef UNICODE_STRING *PUNICODE_STRING;
typedef struct _OBJECT_ATTRIBUTES {
ULONG Length;
HANDLE RootDirectory;
PUNICODE_STRING ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor;
PVOID SecurityQualityOfService;
} OBJECT_ATTRIBUTES;
typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES;
typedef DWORD(WINAPI *NTCREATETHREADEX)
(
PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
HANDLE ProcessHandle,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
BOOL CreateSuspended,
DWORD dwStackSize,
DWORD dw1,
DWORD dw2,
LPVOID Unknown
);
int main()
{
cout << sizeof(void*) << endl;
privileges(); //don't mind of the result, because maybe it fails because you already have that privilege
DWORD pid = getPid("explorer.exe");
if (pid == 0) return 1; //error
HANDLE p;
p = OpenProcess(CREATE_THREAD_ACCESS, false, pid);
if (p == NULL) return 1; //error
char * dll = "E:\\logger_mailer.dll";
BOOL is32 = FALSE;
BOOL fnWow64Ret = IsWow64Process(p, &is32);
if (!fnWow64Ret)
{
cout<<"Error!!!!!!"<<endl;
return 1;
}
//if (is32) //If true process is 32 bit
// dll = "D:\\logger_mailer.dll";
//else
//{
// dll = "D:\\logger_mailer.dll";
// //cout<<"Error"<<endl;
//}
unsigned long LoadLib = (unsigned long)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
LPVOID DataAddress = VirtualAllocEx(p, NULL, strlen(dll) + 1, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(p, DataAddress, dll, strlen(dll), NULL);
HANDLE thread;
NTCREATETHREADEX NtCreateThreadEx = (NTCREATETHREADEX)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtCreateThreadEx");
if (NtCreateThreadEx) {
NtCreateThreadEx(&thread, GENERIC_ALL, NULL, p, (LPTHREAD_START_ROUTINE)LoadLib, DataAddress, FALSE, NULL, NULL, NULL, NULL);
}
else {
thread = CreateRemoteThread(p, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLib, DataAddress, NULL, NULL);
}
if (thread != 0){
//injection completed
WaitForSingleObject(thread, INFINITE); //this waits untill thread thread has finished
VirtualFree(dll, 0, MEM_RELEASE); //free myFunc memory
VirtualFree(DataAddress, 0, MEM_RELEASE); //free data memory
CloseHandle(thread);
CloseHandle(p); //don't wait for the thread to finish, just close the handle to the process
cout << "Injection completed!" << endl;
}
else{
cout << "Error!" << endl;
}
system("PAUSE");
return EXIT_SUCCESS;
}
DWORD getPid(string procName){
HANDLE hsnap;
PROCESSENTRY32 pt;
hsnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
pt.dwSize = sizeof(PROCESSENTRY32);
do{
if (!strcmp(pt.szExeFile, procName.c_str())){
DWORD pid = pt.th32ProcessID;
CloseHandle(hsnap);
return pid;
}
} while (Process32Next(hsnap, &pt));
CloseHandle(hsnap);
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;
}
编辑:所以,在 David 和 Harry 基本上是哄骗我之后,我发现是我的 .dll 代码失败了。此外,我不需要使用 NtCreateThreadEx(),因为 CreateRemoteThread() 确实适用于 win 7 x64。 SO和其他网站上的许多帖子另有说明。显示一个简单的消息框进行验证。
奇怪的是 NtCreateThreadEx() 在管理员模式下工作,而不是在标准模式下。
【问题讨论】:
-
听起来编译器已经优化了该代码。
-
只是一个指针local var的赋值。编译器不需要 var。
-
你的问题是什么?你想了解调试器的行为吗
-
你读错了。如果你需要帮助,你应该问真正的问题,而不是给我们虚假的线索和不必要的 asm。
-
要诊断实际问题,您需要做的主要事情是添加错误检查,以便您知道哪个 API 调用失败,以及错误代码是什么。有了这些信息,我们或许可以提供帮助。
标签: windows winapi dll privileges dll-injection