I trying to write a very simple app to debug a Win32 64-bit app. My end goal is to get the TIB and PEB of the remote thread, but for some reason the way I did this on 32-bit app is not working for 64-bit ones (Aside from looking at Esp vs Rsp and checking SegFs vs SegGs). The code I'm trying to use is here:
#include <windows.h>
#include <stdio.h>
#include <tlhelp32.h>
int main(int argc, char *argv[]){
LDT_ENTRY entry;
DWORD pid;
HANDLE hThread;
HANDLE hSnapshot;
CONTEXT context;
context.ContextFlags = CONTEXT_CONTROL;
if(argc < 2){
printf("Usage: %s PID\n", argv[0]);
exit(1);
}
pid = atoi(argv[1]);
THREADENTRY32 te32;
te32.dwSize = sizeof(te32);
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,0);
while(Thread32Next(hSnapshot, &te32)){
if(pid == te32.th32OwnerProcessID){
hThread = OpenThread(THREAD_ALL_ACCESS, 0, te32.th32ThreadID);
if(!hThread)
exit(1);
if(SuspendThread(hThread) == (DWORD) -1)
exit(1);
if(!GetThreadContext(hThread, &context))
exit(1);
printf("Rsp = 0x%x\n", context.Rsp);
if(!GetThreadSelectorEntry(hThread, context.SegGs, &entry)){
LPSTR buff = NULL;
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL,
GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&buff, 0, NULL);
printf("Error: %s\n", buff); //ERROR_NOT_SUPPORTED 50 0x32 The request is not supported.
LocalFree(buff);
exit(1);
}
}
}
CloseHandle(hSnapshot);
return 0;
}
but it's always throwing an error at "GetThreadSelectorEntry". The error code that's thrown is ERROR_NOT_SUPPORTED: The request is not supported.
I am not able to understand why it's not supported. Does anyone know why?
[EDIT]
Okay GetThreadSelectorEntry is not available to x86_64 processes, does anyone know how I can get the TIB/PEB addresses of a remote process?
I want to make like a function with an argument stdvector::<std::string> of process names and std::vector<std::string> of .dll's to find in them and feed it into a function and get like PROCESSENTRY32 info std::vector<PROCESSENTRY32> returned of anything that matches the names.
You can google but won't find much as I have thanks for helping new to winapi but not to figuring things out
There is a perfect example to do exactly what you want on MSDN here. The relevant code is copied below. As the introduction to the sample says
To determine which processes have loaded a particular DLL, you must enumerate the modules for each process. The following sample code uses the EnumProcessModules function to enumerate the modules of current processes in the system.
Now the sample code
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <psapi.h>
// To ensure correct resolution of symbols, add Psapi.lib to TARGETLIBS
// and compile with -DPSAPI_VERSION=1
int PrintModules( DWORD processID )
{
HMODULE hMods[1024];
HANDLE hProcess;
DWORD cbNeeded;
unsigned int i;
// Print the process identifier.
printf( "\nProcess ID: %u\n", processID );
// Get a handle to the process.
hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
FALSE, processID );
if (NULL == hProcess)
return 1;
// Get a list of all the modules in this process.
if( EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded))
{
for ( i = 0; i < (cbNeeded / sizeof(HMODULE)); i++ )
{
TCHAR szModName[MAX_PATH];
// Get the full path to the module's file.
if ( GetModuleFileNameEx( hProcess, hMods[i], szModName,
sizeof(szModName) / sizeof(TCHAR)))
{
// Print the module name and handle value.
_tprintf( TEXT("\t%s (0x%08X)\n"), szModName, hMods[i] );
}
}
}
// Release the handle to the process.
CloseHandle( hProcess );
return 0;
}
int main( void )
{
DWORD aProcesses[1024];
DWORD cbNeeded;
DWORD cProcesses;
unsigned int i;
// Get the list of process identifiers.
if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
return 1;
// Calculate how many process identifiers were returned.
cProcesses = cbNeeded / sizeof(DWORD);
// Print the names of the modules for each process.
for ( i = 0; i < cProcesses; i++ )
{
PrintModules( aProcesses[i] );
}
return 0;
}
The only change you will need to make is to push-back the module names of interest to your std::vector<std::string> beforehand and then search that vector with the enumerated module names instead of printing them.
I run this sample cod, and i get run time exception
#include "stdafx.h"
#include <iostream>
using namespace std;
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
using namespace cv;
int _tmain(int argc, char** argv)
{
//IplImage* img = cvLoadImage( "Walk1001.jpg" ,1 );
IplImage* img =cvLoadImage( argv[1] );
if(!img)
cout << "Could not open or find the image" << endl ;
cvNamedWindow( "Example1", 1 );
cvShowImage( "Example1", img );
cvWaitKey(0);
cvReleaseImage( &img );
cvDestroyWindow( "Example1" );
return 0;
}
when i use IplImage* img = cvLoadImage( "Walk1001.jpg" ,1 ); instead of this IplImage* img =cvLoadImage( argv[1] ); program runs fine. but otherwise i got error.
What is to do with argv. i have came across many programs in which image is loaded through some argv[] syntex! how to use this array (argv[]) or what else?
to use the argv array, you've got to supply arguments to your program (from the cmdline, or similar)
prog.exe Walk1001.jpg 19
now argv holds 3 elements, [ "prog.exe", "Walk1001.jpg", "19" ], and argc==3
in your program , do:
char * imgPath="Walk1001.jpg"; // having defaults is a good idea
if ( argc > 1 ) // CHECK if there's actual arguments !
{
imgPath = argv[1]; // argv[0] holds the program-name
}
int number = 24;
if ( argc > 2 ) // CHECK again, if there's enough arguments
{
number = atoi(argv[2]); // you get the picture..
}
sidenote: you seem to be a beginner (nothing wrong with that!), the opencv api has changed over the years, please don't use IplImage* and cv*Functions(the 1.0 api),
use cv::Mat and functions from cv:: namespace.
using namespace cv;
int main(int argc, char** argv)
{
char * imgPath="Walk1001.jpg";
if ( argc > 1 )
{
imgPath = argv[1];
}
Mat img = imread( imgPath );
if ( img.empty() )
{
cout << "Could not open or find the image" << endl ;
return 1;
}
namedWindow( "Example1", 1 );
imshow( "Example1", img );
waitKey(0);
// no, you don't have to release Mat !
return 0;
}
I am getting run time exception. the error is line 2482 unknown function in array.cpp? I think i get this message from imshow after debugging. I'm using Mat img=imread("walk100.jpg"); but the img.total() returning NULL. why imread is returning NULL. cvload is working perfectly.
I got this solved, on the web i came to know about ***d.dll. while adding dll files, I omitted the d, that is for release mode not for debug mode. So I just place "d", like opencv_core244d.dll instead of opencv_core244.dll
thanks all for your contribution
-edit- it seems to be a problem with path and not being able to find its bin/ folder. Even though the g++ is in that bin directory.
I am trying to launch g++ on windows in my app but i get the error below. How do i fix it? side note i can do g++ dummy.cpp in the prompt with no problem.
args -o file.exe -x c++ -
stdout
: CreateProcess: No such file or directory
-edit- my code is...
#include <windows.h>
#include <stdio.h>
#include <strsafe.h>
#include <ios>
#include <iostream>
#include <fstream>
#include <sstream>
#include <exception>
#include <string>
#include <deque>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
string gcc_bin="E:/dev/external/MinGW/bin/g++.exe";
string gcc_folder="E:/dev/external/MinGW/bin/";
int launch_gcc(ostringstream&o);
int main(){
ostringstream osz;
osz << "#include <cstdio>" << endl << "int main(){ printf(\"hello\"); } return 4; }";
{
launch_gcc(osz);
}
return 0;
}
void ErrorExit(PTSTR);
int launch_gcc(ostringstream&o)
{
char buf2[4096];
char buf[4096];
ExpandEnvironmentStrings("%PATH%", buf, 4095);
OutputDebugString(buf);
sprintf(buf2, "PATH=%s;%s;\0\0", gcc_folder.c_str(), buf);
STARTUPINFO startupInfo;
PROCESS_INFORMATION processInformation;
HANDLE g_hChildStd_IN_Rd = NULL;
HANDLE g_hChildStd_IN_Wr = NULL;
HANDLE g_hChildStd_OUT_Rd = NULL;
HANDLE g_hChildStd_OUT_Wr = NULL;
HANDLE g_hChildStd_ERR_Rd = NULL;
HANDLE g_hChildStd_ERR_Wr = NULL;
HANDLE g_hInputFile = NULL;
SECURITY_ATTRIBUTES saAttr;
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
if ( ! CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0) )
ErrorExit(TEXT("StdoutRd CreatePipe"));
if ( ! SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0) )
ErrorExit(TEXT("Stdout SetHandleInformation"));
if ( ! CreatePipe(&g_hChildStd_ERR_Rd, &g_hChildStd_ERR_Wr, &saAttr, 0) )
ErrorExit(TEXT("StderrRd CreatePipe"));
if ( ! SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0) )
ErrorExit(TEXT("Stderr SetHandleInformation"));
if (! CreatePipe(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, &saAttr, 0))
ErrorExit(TEXT("Stdin CreatePipe"));
if ( ! SetHandleInformation(g_hChildStd_IN_Wr, HANDLE_FLAG_INHERIT, 0) )
ErrorExit(TEXT("Stdin SetHandleInformation"));
ZeroMemory( &startupInfo, sizeof(STARTUPINFO) );
startupInfo.cb = sizeof(STARTUPINFOA);
startupInfo.hStdError = g_hChildStd_OUT_Wr;
startupInfo.hStdOutput = g_hChildStd_ERR_Wr;
startupInfo.hStdInput = g_hChildStd_IN_Rd;
startupInfo.dwFlags |= STARTF_USESTDHANDLES;
ZeroMemory( &processInformation, sizeof(PROCESS_INFORMATION) );
bool bSuccess = CreateProcess(
gcc_bin.c_str(),
" -o \"c:/dev/src/git/myprj/theout.exe\" -x c++ -",
0,
0,
1,
NORMAL_PRIORITY_CLASS,
0,//buf2,
0,//gcc_folder.c_str(),
&startupInfo,
&processInformation
);
if ( ! bSuccess )
ErrorExit(TEXT("CreateProcess"));
else
{
// Close handles to the child process and its primary thread.
// Some applications might keep these handles to monitor the status
// of the child process, for example.
CloseHandle(processInformation.hProcess);
CloseHandle(processInformation.hThread);
}
{
DWORD dwRead, dwWritten;
BOOL bSuccess = FALSE;
auto sz=o.str();
bSuccess = WriteFile(g_hChildStd_IN_Wr, sz.c_str(), sz.size(), &dwWritten, NULL);
//if ( ! bSuccess ) break;
if ( ! CloseHandle(g_hChildStd_IN_Wr) )
ErrorExit(TEXT("StdInWr CloseHandle"));
}
#define BUFSIZE 1024*4
{
DWORD dwRead, dwWritten;
CHAR chBuf[BUFSIZE];
BOOL bSuccess = FALSE;
HANDLE hParentStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
chBuf[0]=0;
if (!CloseHandle(g_hChildStd_OUT_Wr))
ErrorExit(TEXT("StdOutWr CloseHandle"));
for (;;)
{
bSuccess = ReadFile( g_hChildStd_OUT_Rd, chBuf, BUFSIZE, &dwRead, NULL);
if( ! bSuccess || dwRead == 0 ) break;
bSuccess = WriteFile(hParentStdOut, chBuf,
dwRead, &dwWritten, NULL);
chBuf[dwWritten]=0;
if (! bSuccess ){
printf("%s", chBuf);
break;
}
}
}
{
DWORD dwRead, dwWritten;
CHAR chBuf[BUFSIZE];
BOOL bSuccess = FALSE;
HANDLE hParentStdErr = GetStdHandle(STD_ERROR_HANDLE);
if (!CloseHandle(g_hChildStd_ERR_Wr))
ErrorExit(TEXT("StdOutWr CloseHandle"));
for (;;)
{
bSuccess = ReadFile( g_hChildStd_ERR_Rd, chBuf, BUFSIZE, &dwRead, NULL);
if( ! bSuccess || dwRead == 0 ) break;
bSuccess = WriteFile(hParentStdErr, chBuf,
dwRead, &dwWritten, NULL);
chBuf[dwWritten]=0;
if (! bSuccess ){
printf("%s", chBuf);
break;
}
}
auto a=1;
}
return 0;
}
void ErrorExit(PTSTR lpszFunction)
{
LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
DWORD dw = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL );
lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
(lstrlen((LPCTSTR)lpMsgBuf)+lstrlen((LPCTSTR)lpszFunction)+40)*sizeof(TCHAR));
StringCchPrintf((LPTSTR)lpDisplayBuf,
LocalSize(lpDisplayBuf) / sizeof(TCHAR),
TEXT("%s failed with error %d: %s"),
lpszFunction, dw, lpMsgBuf);
MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);
LocalFree(lpMsgBuf);
LocalFree(lpDisplayBuf);
ExitProcess(1);
}
Try to add the path to g++ compiler into PATH environment variable:
TCHAR *path;
TCHAR *newpath;
DWORD dwSize = GetEnvironmentVariable(TEXT("PATH"), NULL, 0);
path = new TCHAR[dwSize];
GetEnvironmentVariable(TEXT("PATH"), path, dwSize);
dwSize += MAX_PATH;
newpath = new TCHAR[dwSize];
_tcscpy_s(newpath, dwSize, TEXT("E:\\dev\\external\\MinGW\\bin;"));
_tcscat_s(newpath, dwSize, path);
SetEnvironmentVariable(TEXT("PATH"), newpath);
delete[] path;
delete[] newpath;
At this point environment block of your process contains PATH variable that includes the path to g++ compiler. Note: this does not affect user's environment.
You can use char instead of TCHAR, and strcpy, strcat. This way will work in both cases: with Unicode enabled and without Unicode support.
It is very likely that double instances of the compiler exist on the system.
If so, try the following for experiment so that the one under current path could run for the source compile:
D:\cmn_dev\mingw64\bin>.\g++ HelloGcc.cpp -o Hello.exe
Hope this could be of help. Regards.
Which GCC for windows are you using? MinGW, Cygwin, something else?
Have you tried logging in and out again as indicated in this question? CreateProcess: No such file or directory
On Windows, GCC needs its bin directory to be on the PATH, it won't look in the directory of its own binary. Try putting something like
wchar_t buf[4096];
ExpandEnvironmentStringsW(L"%PATH%", buf, 4095);
OutputDebugStringW(buf);
into your program before the call to g++ to make sure the directory is on the path for your program's environment (if you're not running your program in a debugger, use wprintf instead)
Watch out if you tried to install GCC on a path with a space character in it, both MinGW and Cygwin warn against this.
I have had the same issue and got it resolved after adding the "C:\MinGW\msys\1.0\bin" to the PATH system variable.
Use Sysinternals ProcessMonitor (http://technet.microsoft.com/en-us/sysinternals/bb896645) to trace the system calls that are issued by your code (CreateFile, CreateProcess, Registry queries) along with their success and return value. This also shows all different attempts to find the executable which is not found by your code - most times this makes it obvious, which mistake (e.g. typo, escaping, white-space in path etc.) caused the code not to find the g++ executable.
Use Sysinternals ProcessMonitor like BertNase said. What you do is find the .exe name that is doing the compiling under the Process Name column, like gcc.exe. Then look in the Result column and anything that is not a SUCCESS check it out. I think what you are looking for is a NAME NOT FOUND result though.
I had this same problem and did what I just mentioned above, I found that gcc.exe was getting a NAME NOT FOUND result for cc1obj.exe. So I made an educated guess and went into my MinGW folder under \libexec\gcc\mingw32\4.5.0 (the version number might not be the same for you) and made a copy of cc1.exe then renamed it as cc1obj.exe. And wala, that fixed the problem.
You probably aren't missing the same file but it sounds like following this process will fix it.
I got a problem yesterday with a program not being able to handle a path like this:
<some stuff>;%ProgramFiles%\path\to\bins;<some other stuff>
I replaced it with :
<some stuff>;C:\Program Files\path\to\bins;<some other stuff>
and it worked. You might want to check this out
The error you get say that the function of gcc "CreateProcess" try to access some file and can't find it.
Obviously if gcc catch the error, it's running, so nothing wrong with your PATH.
However gcc can't find a program or a library needed for the compilation. It's a strange error that I know on mingw32. My best advice will be to re-installed mingw32. You may have change some file use by the program.
I have also faced the problem while setting up Atom. But later I found out that my MinGW was copied from Codeblocks folder. Reinstalling the packages through official MinGW installer and adding the directory path (for my case C:\MinGW\bin) in
Advance System Settings>Environment Variables > Path
solved the problem for me
Old thread but who knows it can help.
For me, I replaced the complete path with the location of the compiler.
So:
set path="< folder that contains the compiler>"
I think that maybe the current path has some elements in it that are not parsed properly by the compiler (no double quotes, no spaces, etc)