C++ 使用外壳代码调用windows API函数
目标 我正在尝试一个简单的外壳代码练习-使用CreateRemoteThread在远程进程上调用“OutputDebugStringA”,它将激活外壳代码-这个练习没有dll注入 问题 我不知道远程进程中“OutputDebugStringA”的地址,只知道本地进程中的地址 到目前为止我一直在尝试的C++ 使用外壳代码调用windows API函数,c++,windows,winapi,shellcode,C++,Windows,Winapi,Shellcode,目标 我正在尝试一个简单的外壳代码练习-使用CreateRemoteThread在远程进程上调用“OutputDebugStringA”,它将激活外壳代码-这个练习没有dll注入 问题 我不知道远程进程中“OutputDebugStringA”的地址,只知道本地进程中的地址 到目前为止我一直在尝试的 int main() { char ShellCode[] = "\x48\x8d\x0c\x25\x10\x9c\x8c\x4c\xff\x14\x25\x00\x01\x8d\x4c"; /*
int main() {
char ShellCode[] = "\x48\x8d\x0c\x25\x10\x9c\x8c\x4c\xff\x14\x25\x00\x01\x8d\x4c";
/*
* Get process handle passing in the process ID.
*/
int32_t nProcID = 21440;
const HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, nProcID);
if (NULL == hProcess) {
printf("Error: the specified process couldn't be found.\n");
}
const LPVOID arg = (LPVOID)VirtualAllocEx(hProcess, NULL, sizeof(ShellCode), MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (NULL == arg) {
int32_t nLastErrorCode = GetLastError();
printf("Error: the memory could not be allocated inside the chosen process. Error code - %d.\n", nLastErrorCode);
}
const int32_t nBytesWritten = WriteProcessMemory(hProcess, arg, ShellCode, sizeof(ShellCode), NULL);
if (0 == nBytesWritten) {
int32_t nLastErrorCode = GetLastError();
printf("Error: there was no bytes written to the process's address space. Error code - %d.\n", nLastErrorCode);
}
const HANDLE hThreadID = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)arg , NULL, NULL, NULL);
if (NULL == hThreadID) {
int32_t nLastErrorCode = GetLastError();
printf("Error: the remote thread could not be created. Error code - %d.\n", nLastErrorCode);
}
else {
printf("Success: the remote thread was successfully created.\n");
}
/*
* Close the handle to the process, because we've already injected the DLL.
*/
CloseHandle(hProcess);
getchar();
return 0;
}
我尝试的
伪装输出
然后在线将其转换为外壳代码,然后用新的外壳代码调用我的代码。但是远程进程不熟悉这些地址。如果您只想知道
OutputDebugStringA
的地址(假设外壳代码可以工作),那么它与当前进程相同。因此,您可以通过执行LPVOID函数\u addr=reinterpret\u cast(GetProcAddress(GetModuleHandleA(“kernel32.dll”),“OutputDebugStringA”)代码>然后,您可以根据需要使用函数\u addr
因为kernel32.dll
在每个进程中都有相同的基址,所以相对虚拟地址将是相同的,因此地址将是相同的。这根本不是“外壳代码”。只需使用OutputDebugString()调用LoadLibrary()创建一个DLL来注入它。第一个是使用dll进行注入。在第二种方法中,您应该只通过在远程进程上分配内存来注入外壳代码,编写外壳代码,然后使用CreatRemoteThread函数调用它枚举远程进程的模块。查找包含函数的模块。阅读该模块的PE头以确定入口点在何处。您需要有关OutputDebugString()如何在远程进程中加载的信息,然后将代码调用注入其真实地址。@sev:如果您正在运行32位进程并希望将代码注入64位进程,则无效。通常不正确。在具有不同位的进程中,kenel32.dll的基址不相同。由于该问题并不局限于相同比特数的进程,因此建议的答案只是部分解决方案。在windows中,ntdll.dll和kernel32.dll的基址始终相同。0x00007FFFBC300000
和0x748A0000
无疑不是相同的地址。前者是64位进程中kernel32.dll的基址,后者是32位进程中的基址。在我的系统上。今天,你说得对。我假设架构是相同的。