This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 6 years ago.
I can't really see the reason I am getting this error, I have had a look arround and apparently it's something to do with defining a function that does nothing? I can't really tell what the issue is here unfortunately so any help would be appreciated.
Here is my source code:
main.cpp
#include <Windows.h>
#include <tlhelp32.h>
#include <shlwapi.h>
#include <conio.h>
#include <stdio.h>
#include <iostream>
using namespace std;
#define WIN32_LEAN_AND_MEAN
#define CREATE_THREAD_ACCESS (PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ)
BOOL Inject(DWORD pID, const char * DLL_NAME);
DWORD GetTargetThreadIDFromProcName(const char * ProcName);
using namespace std;
char buf[MAX_PATH];
LPVOID RemoteString, LoadLib;
HANDLE Proc;
DWORD pID;
__int32 main()
{
pID = GetTargetThreadIDFromProcName("Program.exe");
buf[MAX_PATH] = {0};
GetFullPathName("DLL.dll", MAX_PATH, buf, NULL);
if(!Inject(pID, buf)) cout << ("Failed to inject!\n\n\n");
system("pause");
return 0;
}
BOOL Inject(DWORD pID, const char * DLL_NAME)
{
char buf[50] = {0};
if(!pID) return false;
Proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID);
if(!Proc) return false;
LoadLib = (LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
RemoteString = (LPVOID)VirtualAllocEx(Proc, NULL, strlen(DLL_NAME), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(Proc, (LPVOID)RemoteString, DLL_NAME, strlen(DLL_NAME), NULL);
CreateRemoteThread(Proc, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLib, (LPVOID)RemoteString, NULL, NULL);
CloseHandle(Proc);
return true;
}
DWORD GetTargetThreadIDFromProcName(const char * ProcName)
{
PROCESSENTRY32 pe;
HANDLE thSnapShot;
BOOL retval, ProcFound = false;
thSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(thSnapShot == INVALID_HANDLE_VALUE) return false;
pe.dwSize = sizeof(PROCESSENTRY32);
retval = Process32First(thSnapShot, &pe);
while(retval)
{
if(StrStrI(pe.szExeFile, ProcName)) return pe.th32ProcessID;
retval = Process32Next(thSnapShot, &pe);
}
return 0;
}
The error I am getting is the following:
main.obj
unresolved external symbol __imp__StrStrIA#8 referenced in function "unsigned long __cdecl GetTargetThreadIDFromProcName(char const *)" (?GetTargetThreadIDFromProcName##YAKPBD#Z)
Injector.exe
1 unresolved externals
Any solutions or just some help on understanding why this occurs would be great!
As mentioned in the comments, it looks like you are not linking with shlwapi.lib. You need to do this in order to call StrStrI.
Related
I am learning about Asynchronous / Overlapped IO in windows. I have written the following code, but it doesn't compile. Where is my mistake? I don't know why we need to call something as FileIoCompletionRoutine and how should I define it?
#include <windows.h>
#include <iostream>
VOID WINAPI FileIOCompletionRoutine(DWORD, DWORD, LPOVERLAPPED);
HANDLE g_HandleEvent;
wchar_t string_data[] = L"Garbage data is absloute thing";
int main(int argc, char* argv[])
{
g_HandleEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
auto file_name = L"Cayot.txt";
auto handle_file = CreateFile(file_name, GENERIC_WRITE, FILE_SHARE_WRITE, 0, CREATE_ALWAYS, FILE_FLAG_OVERLAPPED, 0);
if (handle_file == INVALID_HANDLE_VALUE)
{
std::cout << "File creation is failed." << std::endl;
return -1;
}
OVERLAPPED overlapped_instance = { 0 };
overlapped_instance.hEvent = g_HandleEvent;
WriteFileEx(handle_file, string_data, sizeof(string_data), &overlapped_instance, FileIOCompletionRoutine);
SleepEx(INFINITE, TRUE);
return 0;
}
Error compiler:
error LNK2001: unresolved external symbol "void __stdcall
FileIOCompletionRoutine(unsigned long,unsigned long,struct _OVERLAPPED
*)" (?FileIOCompletionRoutine##YGXKKPAU_OVERLAPPED###Z)
You have merely forward-declared the FileIOCompletionRoutine() function, which satisfies the compiler, but you have not actually implemented the function, so the linker fails to find it.
#include <windows.h>
#include <iostream>
VOID WINAPI FileIOCompletionRoutine(DWORD, DWORD, LPOVERLAPPED);
HANDLE g_HandleEvent;
wchar_t string_data[] = L"Garbage data is absloute thing";
int main(int argc, char* argv[])
{
g_HandleEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
auto file_name = L"Cayot.txt";
auto handle_file = CreateFile(file_name, GENERIC_WRITE, FILE_SHARE_WRITE, 0, CREATE_ALWAYS, FILE_FLAG_OVERLAPPED, 0);
if (handle_file == INVALID_HANDLE_VALUE)
{
std::cout << "File creation is failed." << std::endl;
return -1;
}
OVERLAPPED overlapped_instance = { 0 };
overlapped_instance.hEvent = g_HandleEvent;
WriteFileEx(handle_file, string_data, sizeof(string_data), &overlapped_instance, FileIOCompletionRoutine);
SleepEx(INFINITE, TRUE);
return 0;
}
VOID WINAPI FileIOCompletionRoutine(DWORD dwErrorCode, DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverlapped)
{
// Do something here...
}
#include <iostream>
#include <Windows.h>
#include <TlHelp32.h>
DWORD GetProcId(const char* procName)
{
DWORD procId = 0;
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnap != INVALID_HANDLE_VALUE)
{
PROCESSENTRY32 procEntry;
procEntry.dwSize = sizeof(procEntry);
if (Process32First(hSnap, &procEntry))
{
do
{
if (!_stricmp(procEntry.szExeFile, procName))
{
procId = procEntry.th32ProcessID;
break;
}
} while (Process32Next(hSnap, &procEntry));
}
}
CloseHandle(hSnap);
return procId;
}
int main()
{
const char* dllPath = "C:\\Users\\tme\\Downloads\\dll.dll";
const char* procName = "Application.exe";
DWORD procId = 0;
while (!procId)
{
procId = GetProcId(procName);
Sleep(30);
}
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, 0, procId);
if (hProc && hProc != INVALID_HANDLE_VALUE)
{
void* loc = VirtualAllocEx(hProc, 0, MAX_PATH, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
WriteProcessMemory(hProc, loc, dllPath, strlen(dllPath) + 1, 0);
HANDLE hThread = CreateRemoteThread(hProc, 0, 0, (LPTHREAD_START_ROUTINE)LoadLibraryA, loc, 0, 0);
if (hThread)
{
CloseHandle(hThread);
}
}
if (hProc)
{
CloseHandle(hProc);
}
return 0;
}
In my opinion, it is a false positive.
IDP Generic means: the detection was detected by a Identity Protection detection component and it is a generalized file that got detected.
Practically means that the program behaved in a way that is close to what a malware does. This could be a false positive.
Also, you could refer to this link which could be helpful.
#include <iostream>
#include <Windows.h>
#include <TlHelp32.h>
DWORD GetProcId(const char* procName)
{
DWORD procId = 0;
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnap != INVALID_HANDLE_VALUE)
{
PROCESSENTRY32 procEntry;
procEntry.dwSize = sizeof(procEntry);
if (Process32First(hSnap, &procEntry))
{
do
{
if (!_stricmp(procEntry.szExeFile, procName))
{
procId = procEntry.th32ProcessID;
break;
}
} while (Process32Next(hSnap, &procEntry));
}
}
CloseHandle(hSnap);
return procId;
}
int main()
{
const char* dllPath = "C:\\Users\\%User%\\Desktop\\dll.dll";
const char* procName = "csgo.exe";
DWORD procId = 0;
while (!procId)
{
procId = GetProcId(procName);
Sleep(30);
}
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, 0, procId);
if (hProc && hProc != INVALID_HANDLE_VALUE)
{
void* loc = VirtualAllocEx(hProc, 0, MAX_PATH, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
WriteProcessMemory(hProc, loc, dllPath, strlen(dllPath) + 1, 0);
HANDLE hThread = CreateRemoteThread(hProc, 0, 0, (LPTHREAD_START_ROUTINE)LoadLibraryA,
loc, 0, 0);
if (hThread)
{
CloseHandle(hThread);
}
}
if (hProc)
{
CloseHandle(hProc);
}
return 0;
}
The 2 errors that popped up:
First one:
Error (active) E0167 argument of type "WCHAR *" is incompatible with parameter of type
"const char
Second one:
Error C2664 'int _stricmp(const char *,const char *)': cannot convert argument 1 from
'WCHAR [260]' to 'const char *'
Am I missing inclusions?
basically it won't run correctly, and those are the only 2 errors I get, I fixed the other ones. I just can't seem to figure this one out. I've tried removing some stuff, adding some stuff, but I dont know much about inclusions. If someone who does know inclusions sees a missing one, please let me know. I've tried a lot of stuff on this.
You should include wchar.h
and use wchar_t instead of char.
char normally is 1 byte, while wchar would be 2 bytes.
You can find out more details here:
https://learn.microsoft.com/en-us/cpp/cpp/char-wchar-t-char16-t-char32-t?view=vs-2019
Also, you should use: _wcsicmp instead of _stricmp
See more details here: https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/stricmp-wcsicmp-mbsicmp-stricmp-l-wcsicmp-l-mbsicmp-l?view=vs-2019
i'm using QT to check if process is running and i used the same code in msdn site.
It worked fine on Visual Studio but i'm having a problem making it work on QT.
Here's the code :
bool matchProcessName( DWORD processID, std::string processName)
{
TCHAR szProcessName[MAX_PATH] = TEXT(L"notepad.exe");
// Get a handle to the process.
HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ,
FALSE, processID );
// Get the process name.
if (NULL != hProcess )
{
HMODULE hMod;
DWORD cbNeeded;
if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod),
&cbNeeded) )
{
GetModuleBaseName( hProcess, hMod, szProcessName,
sizeof(szProcessName)/sizeof(TCHAR) );
}
}
// Compare process name with your string
bool matchFound = !_tcscmp(szProcessName, processName.c_str() );
// Release the handle to the process.
CloseHandle( hProcess );
return matchFound;
}
The Error i'm getting is this :
error: cannot convert 'TCHAR*' to 'const char*' for argument '1' to 'int strcmp(const char*, const char*)'
How can i make this work on QT ?
Thanks alot.
Update
I also tried this code :
DWORD FindProcessId(char* processName)
{
char* p = strrchr(processName, '\\');
if(p)
processName = p+1;
PROCESSENTRY32 processInfo;
processInfo.dwSize = sizeof(processInfo);
HANDLE processesSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
if ( processesSnapshot == INVALID_HANDLE_VALUE )
return 0;
Process32First(processesSnapshot, &processInfo);
if ( !strcmp(processName, processInfo.szExeFile) )
{
CloseHandle(processesSnapshot);
return processInfo.th32ProcessID;
}
while ( Process32Next(processesSnapshot, &processInfo) )
{
if ( !strcmp(processName, processInfo.szExeFile) )
{
CloseHandle(processesSnapshot);
return processInfo.th32ProcessID;
}
}
CloseHandle(processesSnapshot);
return 0;
}
I'm also getting an error :cannot convert 'WCHAR*' to 'const char*' for argument '2' to 'int strcmp(const char*, const char*)'
I prefer if i can make 2nd method work !
Thanks again
It has nothing to do with Qt.
In the updated code, PROCESSENTRY32.szExeFile is a TCHAR[],
i.e. it is a WCHAR[] if the macro _UNCODE is defined else is a char[].
So you have to transfer your char *processName to TCHAR[] and use _tcscmp(...) to compare TCHAR[].
Modified code:
#include <Windows.h>
#include <TlHelp32.h>
#include <tchar.h>
#include <Psapi.h>
#include <cstring>
#include <string>
#define MIN(x, y) ((x) > (y)) ? (y) : (x)
void cstringToTCHAR(TCHAR *dst, const char *src, size_t l) {
#if defined(_UNICODE) || defined(UNICODE
mbstowcs(dst, src, l);
#else
memcpy(dst, src, l);
#endif
}
bool matchProcessName( DWORD processID, std::string processName)
{
TCHAR szProcessName[MAX_PATH] = _T("notepad.exe");
// Get a handle to the process.
HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ,
FALSE, processID );
// Get the process name.
if (NULL != hProcess )
{
HMODULE hMod;
DWORD cbNeeded;
if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod),
&cbNeeded) )
{
GetModuleBaseName( hProcess, hMod, szProcessName,
sizeof(szProcessName)/sizeof(TCHAR) );
}
}
// Compare process name with your string
TCHAR systemEncodeProcessName[30];
size_t processNameLen = MIN((processName.size() + 1), 30);
cstringToTCHAR(systemEncodeProcessName, processName.c_str(), processNameLen);
bool matchFound = !_tcscmp(szProcessName, systemEncodeProcessName);
// Release the handle to the process.
CloseHandle( hProcess );
return matchFound;
}
DWORD FindProcessId(char* processName) {
char* p = strrchr(processName, '\\');
if(p) {
processName = p+1;
}
PROCESSENTRY32 processInfo;
processInfo.dwSize = sizeof(processInfo);
HANDLE processesSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
if (processesSnapshot == INVALID_HANDLE_VALUE) {
return 0;
}
//Transfer char array to TCHAR array.
TCHAR systemEncodeProcessName[30];//Maybe need more or dynamic allocation.
size_t processNameLen = MIN((strlen(processName) + 1), 30);
cstringToTCHAR(systemEncodeProcessName, processName, processNameLen);
Process32First(processesSnapshot, &processInfo);
if (!_tcscmp(systemEncodeProcessName, processInfo.szExeFile)) {
CloseHandle(processesSnapshot);
return processInfo.th32ProcessID;
}
while ( Process32Next(processesSnapshot, &processInfo) ) {
if ( !_tcscmp(systemEncodeProcessName, processInfo.szExeFile) ) {
CloseHandle(processesSnapshot);
return processInfo.th32ProcessID;
}
}
CloseHandle(processesSnapshot);
return 0;
}
Update
In Qt creator(3.3.0), the _UNICODE macro looks like missing in Windows platform, just add
DEFINES += _UNICODE
in your .pro file and then run qmake && build.
This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 9 years ago.
I'm trying to inject a dll into a process, but after compiling I get
TestMain.obj : error LNK2019: link to unresolved external symbol __imp__StrStrIA#8 in function "unsigned long __cdecl GetPid(char *)" (?GetPid##YAKPAD#Z). After years of trying find my problem in my code and trying to google it , and meditating with Shaolin monks, I failed.
This is my code:
#include <windows.h>
#include <stdio.h>
#include <tlhelp32.h>
#include <shlwapi.h>
#include <iostream>
#include <conio.h>
using namespace std;
#define CREATE_THREAD_ACCESS (PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ)
bool IsWindowsNT()
{
// check current version of Windows
DWORD version = GetVersion();
// parse return
DWORD majorVersion = (DWORD)(LOBYTE(LOWORD(version)));
DWORD minorVersion = (DWORD)(HIBYTE(LOWORD(version)));
return (version < 0x80000000);
}
BOOL InjectDLL(DWORD ProcessID,char* DLL_NAME)
{
HANDLE Proc;
char buf[50]={0};
LPVOID RemoteString, LoadLibAddy;
if(!ProcessID)
return false;
Proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessID);
LoadLibAddy = (LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
RemoteString = (LPVOID)VirtualAllocEx(Proc, NULL, strlen(DLL_NAME), MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(Proc, (LPVOID)RemoteString, DLL_NAME,strlen(DLL_NAME), NULL);
CreateRemoteThread(Proc, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibAddy, (LPVOID)RemoteString, NULL, NULL);
CloseHandle(Proc);
return true;
}
DWORD GetPid(char *procName)
{
PROCESSENTRY32 pe;
HANDLE thSnapshot;
BOOL retval, ProcFound = false;
thSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(thSnapshot == INVALID_HANDLE_VALUE)
{
cout << "Error: unable to create toolhelp snapshot" << endl;
// MessageBox(NULL, "Error: unable to create toolhelp snapshot", "Loader", NULL);
return false;
}
pe.dwSize = sizeof(PROCESSENTRY32);
retval = Process32First(thSnapshot, &pe);
while(retval)
{
if(StrStrI(pe.szExeFile, procName) )
{
ProcFound = true;
break;
}
retval = Process32Next(thSnapshot,&pe);
pe.dwSize = sizeof(PROCESSENTRY32);
}
if (!ProcFound) return 0;
return pe.th32ProcessID;
}
BOOL LoadDll(char *procName, char *dllName)
{
DWORD ProcID = 0;
ProcID = GetPid(procName);
if(!(InjectDLL(ProcID, dllName)))
{
cout << "Process located, but injection failed" << endl;
_getch();
exit(1);
} // MessageBox(NULL, "Process located, but injection failed", "Loader", NULL);
else
{
cout << " Injection successfull!" << endl;
_getch();
}
return true;
}
int main()
{
char* ProcName = "notepad.exe";
char* DllName = "Main.dll";
LoadDll( ProcName, DllName );
return 0;
}
And my dll:
#include <Windows.h>
DWORD APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved )
{
switch( ul_reason_for_call )
{
case DLL_PROCESS_ATTACH:
// hInstance = (HINSTANCE) hModule;
MessageBox( 0, "HOHOHOOHOHOHO!", "DLLHOOK", MB_OK );
return TRUE;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
So the main problem is that error.Thanks for answering.
Try adding
#pragma comment (lib, 'Shlwapi.lib')
below your other #includes