Access violation reading location 0xc3618000 - c++

I am working on a project about IR Tracking and I am using FreeTrack (www.free-track.net) software for it. FreeTrack offers a sdk folder with their download with C, Matlab and delphi code which can be used to interface the data from FreeTrack to your own writing program in one of these languages.
I started off with Matlab, but when matlab gave a problem, I went on to C++ in Mvisual. This also gives a problem, which seems like the same in Matlab.
Here is the thing:
When i want to read data from a DLL of the freetrack client, I use:
//declare imported function pointers
importGetData getData;
getData = (importGetData)GetProcAddress(hinstLib, "FTGetData");
if (getData(pData))
printf("Yaw: %f\n", data.yaw);
First time it works, but the data is 0. Second time it does it, Mvisual gives the error:
Unhandled exception at 0xc3618000 in FreeTrack.exe: 0xC0000005: Access violation
reading location 0xc3618000.
getData has the adres 0xc3618000.
This only happens when FreeTrack is running. When it isnt, No data is returned from getData.
Any idea's what this can be?
Original code:
#include <windows.h>
#include <stdio.h>
#include <conio.h>
typedef struct
{
float yaw;
float pitch;
float roll;
float x;
float y;
float z;
int dataID;
}FreeTrackData;
// DLL function signatures
// These match those given in FTTypes.pas
// WINAPI is macro for __stdcall defined somewhere in the depths of windows.h
typedef bool (WINAPI *importGetData)(FreeTrackData * data);
typedef char *(WINAPI *importGetDllVersion)(void);
typedef void (WINAPI *importReportID)(int name);
typedef char *(WINAPI *importProvider)(void);
int main(int argc, char **argv)
{
/*while(1){
printf("hello");
}*/
//declare imported function pointers
importGetData getData;
importGetDllVersion getDllVersion;
importReportID reportID;
importProvider provider;
// create variables for exchanging data with the dll
FreeTrackData data;
FreeTrackData *pData;
pData = &data;
char *pDllVersion;
int name = 453;
char *pProvider;
//while(1){};
// Load DLL file
HINSTANCE hinstLib = LoadLibrary("FreeTrackClient.dll");
if (hinstLib == NULL) {
printf("ERROR: unable to load DLL\n");
//return 1;
while(1){};
}
else
{
printf("dll loaded\n");
}
//while(1){};
// Get function pointers
getData = (importGetData)GetProcAddress(hinstLib, "FTGetData");
getDllVersion = (importGetDllVersion)GetProcAddress(hinstLib, "FTGetDllVersion");
//reportID = (importReportID)GetProcAddress(hinstLib, "FTReportID");
reportID = (importReportID)GetProcAddress(hinstLib, "FTReportName");
provider = (importProvider)GetProcAddress(hinstLib, "FTProvider");
// Check they are valid
if (getData == NULL) {
printf("ERROR: unable to find 'FTGetData' function\n");
FreeLibrary(hinstLib);
//return 1;
}
if (getDllVersion == NULL){
printf("ERROR: unable to find 'FTGetDllVersion' function\n");
FreeLibrary(hinstLib);
//return 1;
}
if (reportID == NULL){
printf("ERROR: unable to find 'FTReportID' function\n");
FreeLibrary(hinstLib);
//return 1;
}
if (reportID == NULL){
printf("ERROR: unable to find 'FTProvider' function\n");
FreeLibrary(hinstLib);
//return 1;
}
// Print the address of each function
printf("FTGetData is at address: 0x%x\n",getData);
printf("FTGetDllVersion is at address: 0x%x\n",getDllVersion);
printf("FTReportID is at address: 0x%x\n",reportID);
printf("FTProvider is at address: 0x%x\n",provider);
// Call each function and display result
pDllVersion = getDllVersion();
printf("Dll Version: %s\n", pDllVersion);
pProvider = provider();
printf("Provider: %s\n", pProvider);
reportID(name); //not sure what this does - I guess it tells the dll that I am using it.
system("pause"); //wait till keyboard is pressed before entering main loop
while( kbhit() != 1)
{
//system("cls"); //clear screen
if (getData(pData))
{
printf("Provider: %s\n", pProvider);
printf("Record ID: %d\n" , data.dataID);
printf("Yaw: %5.2f\n" , data.yaw );
printf("Pitch: %5.2f\n" , data.pitch );
printf("Roll: %5.2f\n" , data.roll );
printf("X: %5.2f\n" , data.x );
printf("Y: %5.2f\n" , data.y );
printf("Z: %5.2f\n" , data.z );
}
else
{
printf("Nothing returned from getData\n");
break;
}
}
// Unload DLL file
FreeLibrary(hinstLib);
return 0;
}

You told printf that yaw was a C-style string, but it's a float!

I think this might be caused by the structure definition of FreeTrackData.
I found an updated one from this post, and hope that would help.

Related

What's the actual size of PSAPI_WORKING_SET_INFORMATION buffer used in QueryWorkingSet function of PSAPI.h

I'd like to use the function QueryWorkingSet available in PSAPI, but I'm having trouble to actually define the size of the buffer pv. Here is the code :
#include <Windows.h>
#include <Psapi.h>
#include <iostream>
void testQueryWorkingSet()
{
unsigned int counter;
HANDLE thisProcess = GetCurrentProcess();
SYSTEM_INFO si;
PSAPI_WORKING_SET_INFORMATION wsi, wsi2;
GetSystemInfo(&si);
QueryWorkingSet(thisProcess, &wsi, sizeof(wsi));
DWORD wsi2_buffer_size = (wsi.NumberOfEntries) * sizeof(PSAPI_WORKING_SET_BLOCK);
if (!QueryWorkingSet(thisProcess, &wsi2, wsi2_buffer_size))
{
std::cout << "ERROR CODE : " << GetLastError() << std::endl;
abort();
}
}
int main(int argc, char * argv[])
{
testQueryWorkingSet();
int* test = new int[1000000];
testQueryWorkingSet();
}
I keep ending up with abort() being called and either an error code 24 or 998 during the first call to testQueryWorkingSet(). that I interpret respectively as : wsi2_buffer_size is too low and wsi2_buffer_size is too big.
Now I have no idea of the value this variable should take, I tried :
counting everything including the NumberOfEntries field, that is DWORD wsi2_buffer_size = sizeof(wsi.NumberOfEntries) + wsi.NumberOfEntries * sizeof(PSAPI_WORKING_SET_BLOCK); => error 998;
counting only the number of entries, that is the code given above => error 998;
the size of the variable wsi2, that is DWORD wsi2_buffer_size = sizeof(wsi2); => error 24;
There has to be something I do not understand in the way we're supposed to use this function but I can't find what. I tried to adapt the code given there, that is :
#include <Windows.h>
#include <Psapi.h>
#include <iostream>
void testQueryWorkingSet()
{
unsigned int counter;
HANDLE thisProcess = GetCurrentProcess();
SYSTEM_INFO si;
PSAPI_WORKING_SET_INFORMATION wsi_1, * wsi;
DWORD wsi_size;
GetSystemInfo(&si);
wsi_1.NumberOfEntries = 0;
QueryWorkingSet(thisProcess, (LPVOID)&wsi_1, sizeof(wsi));
#if !defined(_WIN64)
wsi_1.NumberOfEntries--;
#endif
wsi_size = sizeof(PSAPI_WORKING_SET_INFORMATION)
+ sizeof(PSAPI_WORKING_SET_BLOCK) * wsi_1.NumberOfEntries;
wsi = (PSAPI_WORKING_SET_INFORMATION*)HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY, wsi_size);
if (!QueryWorkingSet(thisProcess, (LPVOID)wsi, wsi_size)) {
printf("# Second QueryWorkingSet failed: %lu\n"
, GetLastError());
abort();
}
}
int main(int argc, char * argv[])
{
testQueryWorkingSet();
int* test = new int[1000000];
testQueryWorkingSet();
}
This code is working for only 1 call to testQueryWorkingSet(), the second one is aborting with error code 24. Here are the questions in brief :
How would you use QueryWorkingSet in a function that you could call multiple times successively?
What is representing the value of the parameter cb of the documentation given a PSAPI_WORKING_SET_INFORMATION?
Both examples are completely ignoring the return value and error code of the 1st call of QueryWorkingSet(). You are doing error handling only on the 2nd call.
Your 1st example fails because you are not taking into account the entire size of the PSAPI_WORKING_SET_INFORMATION when calculating wsi2_buffer_size for the 2nd call of QueryWorkingSet(). Even if the 1st call were successful, you are not allocating any additional memory for the 2nd call to fill in, if the NumberOfEntries returned is > 1.
Your 2nd example is passing in the wrong buffer size value to the cb parameter of the 1st call of QueryWorkingSet(). You are passing in just the size of a single pointer, not the size of the entire PSAPI_WORKING_SET_INFORMATION. Error 24 is ERROR_BAD_LENGTH. You need to use sizeof(wsi_1) instead of sizeof(wsi).
I would suggest calling QueryWorkingSet() in a loop, in case the working set actually changes in between the call to query its size and the call to get its data.
Also, be sure you free the memory you allocate when you are done using it.
With that said, try something more life this:
void testQueryWorkingSet()
{
HANDLE thisProcess = GetCurrentProcess();
PSAPI_WORKING_SET_INFORMATION *wsi, *wsi_new;
DWORD wsi_size;
ULONG_PTR count = 1; // or whatever initial size you want...
do
{
wsi_size = offsetof(PSAPI_WORKING_SET_INFORMATION, WorkingSetInfo[count]);
wsi = (PSAPI_WORKING_SET_INFORMATION*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, wsi_size);
if (!wsi)
{
printf("HeapAlloc failed: %lu\n", GetLastError());
abort();
}
if (QueryWorkingSet(thisProcess, wsi, wsi_size))
break;
if (GetLastError() != ERROR_BAD_LENGTH)
{
printf("QueryWorkingSet failed: %lu\n", GetLastError());
HeapFree(GetProcessHeap(), 0, wsi);
abort();
}
count = wsi->NumberOfEntries;
HeapFree(GetProcessHeap(), 0, wsi);
}
while (true);
// use wsi as needed...
HeapFree(GetProcessHeap(), 0, wsi);
}

Calling a Constructor in a custom .NET Core Host

I am trying to write a .NET Core host using coreclr.h. To do this I am trying to create function pointers to the c# code. I am able to call the static methods from my host, but calling the methods that depend on an object directly are not able to be called, ideally I would like to be able to call the constructor and all non-static methods from the C++ without modifying the C#. I can call Multiply5 and Main fine, but there is a segfault when the Program constructor or Add is called, is there any way to fix this? This is a Linux system so C++/CLI is not an option.
C++
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include "coreclrhost.h"
#include <iostream>
#define MANAGED_ASSEMBLY "TestConsole.dll"
#include <dirent.h>
#include <dlfcn.h>
#include <limits.h>
#define FS_SEPARATOR "/"
#define PATH_DELIMITER ":"
#define MAX_PATH PATH_MAX
#define CORECLR_FILE_NAME "libcoreclr.so"
// Function pointer types for the managed call and callback
typedef int (*report_callback_ptr)(int progress);
typedef char* (*doWork_ptr)(const char* jobName, int iterations, int dataSize, double* data, report_callback_ptr callbackFunction);
typedef int (*Multiply5_ptr)(const int i);
typedef (*Constructor_ptr)(int i1, int i2);
typedef int (*ReturnInt_ptr)();
void BuildTpaList(const char* directory, const char* extension, std::string& tpaList);
int main(int argc, char* argv[])
{
// Get the current executable's directory
// This sample assumes that both CoreCLR and the
// managed assembly to be loaded are next to this host
// so we need to get the current path in order to locate those.
char runtimePath[MAX_PATH];
#if WINDOWS
GetFullPathNameA(argv[0], MAX_PATH, runtimePath, NULL);
#elif LINUX
realpath(argv[0], runtimePath);
#endif
char *last_slash = strrchr(runtimePath, FS_SEPARATOR[0]);
if (last_slash != NULL)
*last_slash = 0;
// Construct the CoreCLR path
// For this sample, we know CoreCLR's path. For other hosts,
// it may be necessary to probe for coreclr.dll/libcoreclr.so
std::string coreClrPath(runtimePath);
coreClrPath.append(FS_SEPARATOR);
coreClrPath.append(CORECLR_FILE_NAME);
// Construct the managed library path
std::string managedLibraryPath(runtimePath);
managedLibraryPath.append(FS_SEPARATOR);
managedLibraryPath.append(MANAGED_ASSEMBLY);
//
// STEP 1: Load CoreCLR (coreclr.dll/libcoreclr.so)
//
#if WINDOWS
// <Snippet1>
HMODULE coreClr = LoadLibraryExA(coreClrPath.c_str(), NULL, 0);
// </Snippet1>
#elif LINUX
void *coreClr = dlopen(coreClrPath.c_str(), RTLD_NOW | RTLD_LOCAL);
#endif
if (coreClr == NULL)
{
printf("ERROR: Failed to load CoreCLR from %s\n", coreClrPath.c_str());
return -1;
}
else
{
printf("Loaded CoreCLR from %s\n", coreClrPath.c_str());
}
//
// STEP 2: Get CoreCLR hosting functions
//
#if WINDOWS
// <Snippet2>
coreclr_initialize_ptr initializeCoreClr = (coreclr_initialize_ptr)GetProcAddress(coreClr, "coreclr_initialize");
coreclr_create_delegate_ptr createManagedDelegate = (coreclr_create_delegate_ptr)GetProcAddress(coreClr, "coreclr_create_delegate");
coreclr_shutdown_ptr shutdownCoreClr = (coreclr_shutdown_ptr)GetProcAddress(coreClr, "coreclr_shutdown");
// </Snippet2>
#elif LINUX
coreclr_initialize_ptr initializeCoreClr = (coreclr_initialize_ptr)dlsym(coreClr, "coreclr_initialize");
coreclr_create_delegate_ptr createManagedDelegate = (coreclr_create_delegate_ptr)dlsym(coreClr, "coreclr_create_delegate");
coreclr_shutdown_ptr shutdownCoreClr = (coreclr_shutdown_ptr)dlsym(coreClr, "coreclr_shutdown");
#endif
if (initializeCoreClr == NULL)
{
printf("coreclr_initialize not found");
return -1;
}
if (createManagedDelegate == NULL)
{
printf("coreclr_create_delegate not found");
return -1;
}
if (shutdownCoreClr == NULL)
{
printf("coreclr_shutdown not found");
return -1;
}
//
// STEP 3: Construct properties used when starting the runtime
//
// Construct the trusted platform assemblies (TPA) list
// This is the list of assemblies that .NET Core can load as
// trusted system assemblies.
// For this host (as with most), assemblies next to CoreCLR will
// be included in the TPA list
std::string tpaList;
BuildTpaList(runtimePath, ".dll", tpaList);
tpaList.append(managedLibraryPath);
tpaList.append(":");
// <Snippet3>
// Define CoreCLR properties
// Other properties related to assembly loading are common here,
// but for this simple sample, TRUSTED_PLATFORM_ASSEMBLIES is all
// that is needed. Check hosting documentation for other common properties.
const char* propertyKeys[] = {
"TRUSTED_PLATFORM_ASSEMBLIES" // Trusted assemblies
};
const char* propertyValues[] = {
tpaList.c_str()
};
// </Snippet3>
//
// STEP 4: Start the CoreCLR runtime
//
// <Snippet4>
void* hostHandle;
unsigned int domainId;
// This function both starts the .NET Core runtime and creates
// the default (and only) AppDomain
int hr = initializeCoreClr(
runtimePath, // App base path
"SampleHost", // AppDomain friendly name
sizeof(propertyKeys) / sizeof(char*), // Property count
propertyKeys, // Property names
propertyValues, // Property values
&hostHandle, // Host handle
&domainId); // AppDomain ID
// </Snippet4>
if (hr >= 0)
{
printf("CoreCLR started\n");
}
else
{
printf("coreclr_initialize failed - status: 0x%08x\n", hr);
return -1;
}
//
// STEP 5: Create delegate to managed code and invoke it
//
// <Snippet5>
Multiply5_ptr managedDelegate;
// The assembly name passed in the third parameter is a managed assembly name
// as described at https://learn.microsoft.com/dotnet/framework/app-domains/assembly-names
hr = createManagedDelegate(
hostHandle,
domainId,
"TestConsole, Version=1.0.0.0",
"TestConsole.Program",
"Multiply5",
(void**)&managedDelegate);
// </Snippet5>
if (hr >= 0)
{
printf("Managed delegate created\n");
}
else
{
printf("coreclr_create_delegate failed - status: 0x%08x\n", hr);
return -1;
}
int i = 20;
// Invoke the managed delegate and write the returned intS to the console
//char* ret = managedDelegate("Test job", 1, sizeof(int), i, ReportProgressCallback);
int ret = managedDelegate(i);
printf("Managed code returned: %d\n", ret);
Constructor_ptr programDelegate;
hr = createManagedDelegate(hostHandle,
domainId,
"TestConsole, Version=1.0.0.0",
"TestConsole.Program",
"Program",
(void**)&programDelegate);
int i1 = i;
int i2 = ret;
programDelegate(i1,i2);//Will seg fault here
ReturnInt_ptr addDelegate;
hr = createManagedDelegate(hostHandle,
domainId,
"TestConsole, Version=1.0.0.0",
"TestConsole.Program",
"Add",
(void**)&addDelegate);
i = addDelegate(); //Also triggers a seg fault.
printf("Managed code returned: %d\n", i);
// Strings returned to native code must be freed by the native code
#if WINDOWS
CoTaskMemFree(ret);
#elif LINUX
// free(ret);
#endif
//
// STEP 6: Shutdown CoreCLR
//
// <Snippet6>
hr = shutdownCoreClr(hostHandle, domainId);
// </Snippet6>
if (hr >= 0)
{
printf("CoreCLR successfully shutdown\n");
}
else
{
printf("coreclr_shutdown failed - status: 0x%08x\n", hr);
}
return 0;
}
#if WINDOWS
// Win32 directory search for .dll files
// <Snippet7>
void BuildTpaList(const char* directory, const char* extension, std::string& tpaList)
{
// This will add all files with a .dll extension to the TPA list.
// This will include unmanaged assemblies (coreclr.dll, for example) that don't
// belong on the TPA list. In a real host, only managed assemblies that the host
// expects to load should be included. Having extra unmanaged assemblies doesn't
// cause anything to fail, though, so this function just enumerates all dll's in
// order to keep this sample concise.
std::string searchPath(directory);
searchPath.append(FS_SEPARATOR);
searchPath.append("*");
searchPath.append(extension);
WIN32_FIND_DATAA findData;
HANDLE fileHandle = FindFirstFileA(searchPath.c_str(), &findData);
if (fileHandle != INVALID_HANDLE_VALUE)
{
do
{
// Append the assembly to the list
tpaList.append(directory);
tpaList.append(FS_SEPARATOR);
tpaList.append(findData.cFileName);
tpaList.append(PATH_DELIMITER);
// Note that the CLR does not guarantee which assembly will be loaded if an assembly
// is in the TPA list multiple times (perhaps from different paths or perhaps with different NI/NI.dll
// extensions. Therefore, a real host should probably add items to the list in priority order and only
// add a file if it's not already present on the list.
//
// For this simple sample, though, and because we're only loading TPA assemblies from a single path,
// and have no native images, we can ignore that complication.
}
while (FindNextFileA(fileHandle, &findData));
FindClose(fileHandle);
}
}
// </Snippet7>
#elif LINUX
// POSIX directory search for .dll files
void BuildTpaList(const char* directory, const char* extension, std::string& tpaList)
{
DIR* dir = opendir(directory);
struct dirent* entry;
int extLength = strlen(extension);
while ((entry = readdir(dir)) != NULL)
{
// This simple sample doesn't check for symlinks
std::string filename(entry->d_name);
// Check if the file has the right extension
int extPos = filename.length() - extLength;
if (extPos <= 0 || filename.compare(extPos, extLength, extension) != 0)
{
continue;
}
// Append the assembly to the list
tpaList.append(directory);
tpaList.append(FS_SEPARATOR);
tpaList.append(filename);
tpaList.append(PATH_DELIMITER);
// Note that the CLR does not guarantee which assembly will be loaded if an assembly
// is in the TPA list multiple times (perhaps from different paths or perhaps with different NI/NI.dll
// extensions. Therefore, a real host should probably add items to the list in priority order and only
// add a file if it's not already present on the list.
//
// For this simple sample, though, and because we're only loading TPA assemblies from a single path,
// and have no native images, we can ignore that complication.
}
}
#endif
C#
namespace TestConsole
{
public class Program
{
IntTest i;
Program(int i1, int i2){
i = new IntTest(i1,i2);
}
public static void Main()
{
Program p = new Program(23,12);
Console.WriteLine(p.Add());
}
// This test method doesn't actually do anything, it just takes some input parameters,
// waits (in a loop) for a bit, invoking the callback function periodically, and
// then returns a string version of the double[] passed in.
//[return: MarshalAs(UnmanagedType.I4)]
public static int Return5(){
return 5;
}
public int Add(){
return i.Add();
}
private static int Multiply5(int i){
return 5*i;
}
}
}
IntTest is an external library.
So there is no way to do this all free c++, the other option is to wrap the C# method in a static one and create a function pointer that way.

Substitute Console window by Windows Forms

I have created a Win32 Console Application project in Visual Studio 2012 C++.
How can I substitute the Console window by a more appealing GUI like Windows Forms?
int32_t main(int32_t argc, char* argv[])
{
const char *date = "20150428_1\\";
int mode=0;
_CallServerPtr pCallServer;
uint32_t start_address_comp=0;
uint32_t start_address_module=0;
const char* xmlFile_tx_dbb="tx_dbb.xml";;
char str[100] = "\0";
char localeStr[64];
memset(localeStr, 0, sizeof localeStr);
const char *l_path = "..\\XERCES\\Configs\\";
std::string buf = "";
double Fsym_Hz=(1/1.15)*1e9;
int selection=0;
int user_selection=0;
try
{
if (strlen(localeStr))
{
XMLPlatformUtils::Initialize(localeStr);
}
else
{
XMLPlatformUtils::Initialize();
}
}
catch (const XMLException& toCatch)
{
XERCES_STD_QUALIFIER cerr << "Error during initialization! :\n"
<< StrX(toCatch.getMessage()) << XERCES_STD_QUALIFIER endl;
}
static const XMLCh gLS[] = { chLatin_L, chLatin_S, chNull };
DOMImplementation *impl = DOMImplementationRegistry::getDOMImplementation(gLS);
DOMLSParser *parser = ((DOMImplementationLS*)impl)->createLSParser(DOMImplementationLS::MODE_SYNCHRONOUS, 0);
DOMConfiguration *config = parser->getDomConfig();
DOMLSSerializer *theSerializer = ((DOMImplementationLS*)impl)->createLSSerializer();
DOMLSOutput *theOutputDesc = ((DOMImplementationLS*)impl)->createLSOutput();
config->setParameter(XMLUni::fgDOMDatatypeNormalization, true);
DOMCountErrorHandler errorHandler;
config->setParameter(XMLUni::fgDOMErrorHandler, &errorHandler);
XERCES_STD_QUALIFIER ifstream fin;
//reset error count first
errorHandler.resetErrors();*/
// reset document pool
parser->resetDocumentPool();
char* pszHostname = NULL;
pSaIn = 0;
pSaOut = 0;
// Initialize the COM Library
CoInitialize(NULL);
if (!pszHostname)
{
// Create the CallServer server object on the local computer
pCallServer.CreateInstance(CLSID_CallServer);
}
if (pCallServer == NULL)
throw "Failed to create the CallableVEE CallServer object";
// Load the VEE User Function library
char strpath[256];
strcpy (strpath,reposity_path);
strcat (strpath,l_path_vee);
_bstr_t bstrLibPath(strpath);
LibraryPtr pLib = pCallServer->GetLibraries()->Load(bstrLibPath);
// Print out the names of the UserFunctions in this library.
UserFunctionsPtr pUserFuncColl = pLib->GetUserFunctions();
VARIANT_BOOL bDebug = VARIANT_FALSE;
pCallServer->PutDebug(bDebug);
// Variables added by ivi
float *freq =(float *)_aligned_malloc(6,16); // Read frequency vector
// Previous variables
int32_t devIdx;
int32_t modeClock;
int32_t ifType;
const char *devType;
char fpga_device_type[32];
int32_t rc;
int32_t ref_clk=0;
uint32_t carrier=0;
uint32_t odelay_dac0 = 0;
uint32_t odelay_dac1 = 0;
// Parse the application arguments
if(argc!=5) {
printf("Usage: FMCxxxApp.exe {interface type} {device type} {device index} {clock mode} \n\n");
printf(" {interface type} can be either 0 (PCI) or 1 (Ethernet). At CEIT, we use 1 (Ethernet).\n");
printf(" {device type} is a string defining the target hardware (VP680, ML605, ...). At CEIT, we use VC707.\n");
printf(" {device index} is a PCI index or an Ethernet interface index. This value depends on the PC.\n");
printf(" {clock mode} can be either 0 (Int. Clock) or 1 (Ext. Clock)\n");
printf("\n");
printf("\n");
printf("Example: Fmc230APP.exe 1 VC707 0 0\n");
printf("\n");
printf("\n");
printf(" List of NDIS interfaces found in the system {device index}:\n");
printf(" -----------------------------------------------------------\n");
if(sipif_getdeviceenumeration(API_ENUM_DISPLAY)!=SIPIF_ERR_OK) {
printf("Could not obtain NDIS(Ethernet) device enumeration...\n Check if the 4dspnet driver installed or if the service started?\n");
printf("You can discard this error if you do not have any Ethernet based product in use.");
}
if( EXIT_IF_ERRORS)
{
sipif_free();
system("pause");
return -1;
}
...
}
You mean to have the same code in windows forms. That won't work. The printf and other commands work only in a console application. You must to create a windows form application and rewrite the code for it. You must rewrite all commands that don't work in a windows form application. There probably exists a conversion application, but for this short code I think it's better to rewrite it.

Dll injection with GetFullPathNameA not working?

If I explicitly write the address the dll injection works
char s[1000]="E:\\worldisnotenough.dll"; //Works
If I use GetFullPathNameA DLL injections do not work, and they do not give any runtime or compile time errors. I checked this:
char s[1000];
int ax =GetFullPathNameA("worldisnotenough.dll",
1000,
s, //Output to save the full DLL path
NULL);
std::cout<<s; //prints the correct path. Working.
The line cout << s prints the correct path, but DLL injection doesn't happen. No errors occur. I checked VirtualAllocEx, WriteProcessMemory, and CreateRemoteThread, and all of them are working properly.
Edit: complete code
#include <QCoreApplication>
#include<windows.h>
#include<tchar.h>
#include<iostream>
#include "E:/Users/Gen/qt project freiza/FreizaLibrary/freizalibrary.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// FreizaLibrary lib;
// QTextStream s(stdin);
// QString value = s.readLine();
// lib.injection(value.toInt());
int procID = 13044;
HANDLE hHandle = OpenProcess( PROCESS_CREATE_THREAD |
PROCESS_QUERY_INFORMATION |
PROCESS_VM_OPERATION |
PROCESS_VM_WRITE |
PROCESS_VM_READ,
FALSE,
procID );
QString dllName = "worldisnotenough.dll";
QFile myDllFile(dllName);
QFileInfo dllInfo(dllName);
QString str =dllInfo.absoluteFilePath();
char s[]="E:\\Users\\Gen\\qt project freiza\\build-libtester-FreizaKit-Release\\release\\worldisnotenough.dll";
std::cout<<strlen(s)<<"\n";
int ax =GetFullPathNameA("worldisnotenough.dll",
86, //I set it to 1000 before posting this question.
s, //Output to save the full DLL path
NULL);
//qDebug()<< QString::fromUtf8(s) <<" "<< ax;
std::cout<<s<<"size "<<ax;
LPVOID dllPathAddr = VirtualAllocEx(hHandle,
0,
strlen(s),
MEM_RESERVE|MEM_COMMIT,
PAGE_EXECUTE_READWRITE);
std::cout<<" test \n";
std::cout<<(int*)dllPathAddr<<endl;
if(dllPathAddr==NULL)
{
qDebug()<<"virtual failed";
}
size_t x;
int n= WriteProcessMemory(hHandle,
dllPathAddr,
s,
strlen(s),
&x);
if(n==0)
{
qDebug()<<"write failed";
}
std::cout<<endl<<n<<"\t"<<x;
LPVOID addr = (LPVOID)GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryA");
if(addr==NULL)
{
qDebug()<<"get proc failed";
}
HANDLE rThread = CreateRemoteThread(hHandle, NULL, 0, (LPTHREAD_START_ROUTINE)addr,dllPathAddr, 0, NULL);
if(rThread==NULL)
{
qDebug()<<"create remote failed";
}
WaitForSingleObject(rThread, INFINITE);
VirtualFreeEx(hHandle, dllPathAddr, 0, MEM_RELEASE);
CloseHandle(hHandle);
qDebug()<< "done";
return a.exec();
}
And why negative votes?
When I post full code. People say only post the segment of code which is not working.
And I explained the situation to its fullest. Because of these negative votes now I won't be able to ask questions on stackoverflow. Thank you.
Your problem is you are trying to use a statically defined character array as a buffer for GetFullPathNameA!
See here:
char s[]="E:\\Users\\Gen\\qt project freiza\\build-libtester-FreizaKit-Release\\release\\worldisnotenough.dll";
std::cout<<strlen(s)<<"\n";
int ax =GetFullPathNameA("worldisnotenough.dll",
86, //1000 is no good, MAX_PATH is 260
s, //Using 's' as a buffer? Don't do that please!
NULL);
Furthermore when using the ANSI version which you are as denoted by the 'A' a maximum path length of 260 characters is the maximum. MAX_PATH==260
"In the ANSI version of this function, the name is limited to MAX_PATH characters. To extend this limit to 32,767 wide characters, call the Unicode version of the function and prepend "\?\" "
Fixed code: (However I don't use QT so that is missing from here, shouldn't matter though as it wasn't used for anything needed for the injecting to work)
#include <windows.h>
#include <iostream>
#include <tlhelp32.h>
HANDLE GetProcessHandle(wchar_t *ProcessName,ULONG *ReturnedProcessId);
int main(int argc, char *argv[])
{
ULONG procID;
HANDLE hHandle=GetProcessHandle(L"ExeToInjectInto.exe",&procID);
/*HANDLE hHandle=OpenProcess(PROCESS_CREATE_THREAD|PROCESS_QUERY_INFORMATION|PROCESS_VM_OPERATION|
PROCESS_VM_WRITE|PROCESS_VM_READ,FALSE,procID);*/
std::cout<<"handle: "<<hHandle<<" process ID: "<<procID<<"\n";
char s[]="C:\\Users\\DBVM_OS\\CodeBlocksProjects\\HelpFreizaProject\\bin\\Debug\\mytestdll.dll";
std::cout<<s<<"\n"<<strlen(s)<<"\n";
//First Problem:
/*In the ANSI version of this function, the name is limited to MAX_PATH characters.
To extend this limit to 32,767 wide characters, call the Unicode version of the function and prepend "\\?\"
*/
//Second Problem:
/* Don't use a defined static char[] as a buffer! allocate some memory or use the stack */
//char s2[MAX_PATH];
//int ax=GetFullPathNameA("mytestdll.dll",MAX_PATH,s2,0);
char *s2=new char[MAX_PATH];
if(s2==0) return 0;
int ax=GetFullPathNameA("mytestdll.dll",MAX_PATH,s2,0);
std::cout<<s2<<"\nsize returned: "<<ax<<" strlen: "<<strlen(s2)<<"\n";
LPVOID dllPathAddr=VirtualAllocEx(hHandle,0,(strlen(s2)+1),MEM_COMMIT,PAGE_EXECUTE_READWRITE);
std::cout<<"Remotely Allocated String Address: \n";
std::cout<<(int*)dllPathAddr<<"\n";
if(dllPathAddr==0)
{
OutputDebugStringA("VirtualAllocEx failed...");
return 0;
}
SIZE_T x;
BOOL n=WriteProcessMemory(hHandle,dllPathAddr,s2,(strlen(s2)+1),&x);
if(n==FALSE)
{
OutputDebugStringA("write failed");
VirtualFreeEx(hHandle,dllPathAddr,0,MEM_RELEASE);
CloseHandle(hHandle);
return 0;
}
std::cout<<"WriteProcessMemory Success: "<<n<<", Bytes Written: "<<x<<"\n";
LPVOID addr=(LPVOID)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "LoadLibraryA");
if(addr==0)
{
OutputDebugStringA("get proc failed");
VirtualFreeEx(hHandle,dllPathAddr,0,MEM_RELEASE);
CloseHandle(hHandle);
return 0;
}
std::cout<<"LoadLibraryA: "<<addr<<"\n";
HANDLE rThread=CreateRemoteThread(hHandle,0,0,(LPTHREAD_START_ROUTINE)addr,dllPathAddr,0,0);
if(rThread==0)
{
OutputDebugStringA("create remote failed");
VirtualFreeEx(hHandle,dllPathAddr,0,MEM_RELEASE);
CloseHandle(hHandle);
return 0;
}
WaitForSingleObject(rThread,INFINITE);
std::cout<<"DLL Should have been injected successfully at this point...\nFreeing remote string";
BOOL freed=VirtualFreeEx(hHandle,dllPathAddr,0,MEM_RELEASE);
if(freed==0) OutputDebugStringA("Freeing Remote String Failed...");
delete[] s2; //if you dynamically allocated s2 like I've done...
CloseHandle(hHandle);
return 0;
}
HANDLE GetProcessHandle(wchar_t *ProcessName,ULONG *ReturnedProcessId)
{
PROCESSENTRY32W pe;
HANDLE Snap;
ZeroMemory(&pe, sizeof(PROCESSENTRY32W));
pe.dwSize=sizeof(PROCESSENTRY32W);
Snap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
if(Snap==INVALID_HANDLE_VALUE) return 0;
BOOL bProcess=Process32FirstW(Snap,&pe);
while(bProcess)
{
if(_wcsicmp(pe.szExeFile,ProcessName)==0)
{
HANDLE ProcessHandle=OpenProcess(PROCESS_CREATE_THREAD|PROCESS_QUERY_INFORMATION|PROCESS_VM_OPERATION|
PROCESS_VM_WRITE|PROCESS_VM_READ,FALSE,pe.th32ProcessID);
if(ReturnedProcessId!=0)
*ReturnedProcessId=pe.th32ProcessID;
CloseHandle(Snap);
return ProcessHandle;
}
bProcess=Process32NextW(Snap, &pe);
}
if(ReturnedProcessId!=0) *ReturnedProcessId=0;
CloseHandle(Snap);
return 0;
}
you need to use
strlen(s)+1
cause it returnes the lenght of the string without including the terminating null character itself! So VirtualAllocEx and WriteProcessMemory will not write the '\0' char and the filename will terminate at a "random" position in memory.
Also
char s[]="E:\\Users\\Gen\\qt project freiza\\build-libtester-FreizaKit-Release\\release\\worldisnotenough.dll"; //- Length: 93+1
int ax =GetFullPathNameA("worldisnotenough.dll",
sizeof(s), //<-- old: 86 but s[] is 93 + 1 if this has to hold the total path may it was to small?
s, //Output to save the full DLL path
NULL);
looks wong?!

How can you use CaptureStackBackTrace to capture the exception stack, not the calling stack?

I marked up the following code:
#include "stdafx.h"
#include <process.h>
#include <iostream>
#include <Windows.h>
#include <dbghelp.h>
using namespace std;
#define TRACE_MAX_STACK_FRAMES 1024
#define TRACE_MAX_FUNCTION_NAME_LENGTH 1024
int printStackTrace()
{
void *stack[TRACE_MAX_STACK_FRAMES];
HANDLE process = GetCurrentProcess();
SymInitialize(process, NULL, TRUE);
WORD numberOfFrames = CaptureStackBackTrace(0, TRACE_MAX_STACK_FRAMES, stack, NULL);
char buf[sizeof(SYMBOL_INFO)+(TRACE_MAX_FUNCTION_NAME_LENGTH - 1) * sizeof(TCHAR)];
SYMBOL_INFO* symbol = (SYMBOL_INFO*)buf;
symbol->MaxNameLen = TRACE_MAX_FUNCTION_NAME_LENGTH;
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
DWORD displacement;
IMAGEHLP_LINE64 line;
line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
for (int i = 0; i < numberOfFrames; i++)
{
DWORD64 address = (DWORD64)(stack[i]);
SymFromAddr(process, address, NULL, symbol);
if (SymGetLineFromAddr64(process, address, &displacement, &line))
{
printf("\tat %s in %s: line: %lu: address: 0x%0X\n", symbol->Name, line.FileName, line.LineNumber, symbol->Address);
}
else
{
printf("\tSymGetLineFromAddr64 returned error code %lu.\n", GetLastError());
printf("\tat %s, address 0x%0X.\n", symbol->Name, symbol->Address);
}
}
return 0;
}
void function2()
{
int a = 0;
int b = 0;
throw new exception;
}
void function1()
{
int a = 0;
function2();
}
void function0()
{
function1();
}
static void threadFunction(void *param)
{
try
{
function0();
}
catch (...)
{
printStackTrace();
}
}
int _tmain(int argc, _TCHAR* argv[])
{
_beginthread(threadFunction, 0, NULL);
printf("Press any key to exit.\n");
cin.get();
return 0;
}
What it does is, it logs a stack trace, but the problem is that the stack trace it logs does not give me the line numbers that I want. I want it to log the line numbers of the places that threw the exception, on and up the call stack, kind of like in C#. But what it actually does right now, is it outputs the following:
at printStackTrace in c:\users\<yourusername>\documents\visual studio 2013\pr
ojects\stacktracing\stacktracing\stacktracing.cpp: line: 17: address: 0x10485C0
at threadFunction in c:\users\<yourusername>\documents\visual studio 2013\pro
jects\stacktracing\stacktracing\stacktracing.cpp: line: 68: address: 0x10457C0
SymGetLineFromAddr64 returned error code 487.
at beginthread, address 0xF9431E0.
SymGetLineFromAddr64 returned error code 487.
at endthread, address 0xF9433E0.
SymGetLineFromAddr64 returned error code 487.
at BaseThreadInitThunk, address 0x7590494F.
SymGetLineFromAddr64 returned error code 487.
at RtlInitializeExceptionChain, address 0x7713986A.
SymGetLineFromAddr64 returned error code 487.
at RtlInitializeExceptionChain, address 0x7713986A.
The problem I am facing, once again, is that line: 68 in this trace corresponds to the line that calls the method printStackTrace();, while I would like it to give me line number 45, which corresponds to the line which throws the exception: throw new exception; and then continue further up the stack.
How can I achieve this sort of behavior and break into this thread exactly when it throws this exception in order to get a proper stack trace?
PS The code above was run for a console application using MSVC++ with unicode enabled on Windows 8.1 x64 machine, with the application being run as a Win32 application in Debug mode.
On Windows, unhandled C++ exception automatically generates SEH exception. SEH __except block allows to attach a filter that accepts _EXCEPTION_POINTERS structure as a parameter, which contains the pointer to the processor's context record in the moment exception was thrown. Passing this pointer to StackWalk64 function gives the stack trace in the moment of exception. So, this problem can be solved by using SEH-style exception handling instead of C++ style.
Example code:
#include <stdlib.h>
#include <locale.h>
#include <stdio.h>
#include <tchar.h>
#include <process.h>
#include <iostream>
#include <Windows.h>
#include "dbghelp.h"
using namespace std;
const int MaxNameLen = 256;
#pragma comment(lib,"Dbghelp.lib")
void printStack( CONTEXT* ctx ) //Prints stack trace based on context record
{
BOOL result;
HANDLE process;
HANDLE thread;
HMODULE hModule;
STACKFRAME64 stack;
ULONG frame;
DWORD64 displacement;
DWORD disp;
IMAGEHLP_LINE64 *line;
char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)];
char name[MaxNameLen];
char module[MaxNameLen];
PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
// On x64, StackWalk64 modifies the context record, that could
// cause crashes, so we create a copy to prevent it
CONTEXT ctxCopy;
memcpy(&ctxCopy, ctx, sizeof(CONTEXT));
memset( &stack, 0, sizeof( STACKFRAME64 ) );
process = GetCurrentProcess();
thread = GetCurrentThread();
displacement = 0;
#if !defined(_M_AMD64)
stack.AddrPC.Offset = (*ctx).Eip;
stack.AddrPC.Mode = AddrModeFlat;
stack.AddrStack.Offset = (*ctx).Esp;
stack.AddrStack.Mode = AddrModeFlat;
stack.AddrFrame.Offset = (*ctx).Ebp;
stack.AddrFrame.Mode = AddrModeFlat;
#endif
SymInitialize( process, NULL, TRUE ); //load symbols
for( frame = 0; ; frame++ )
{
//get next call from stack
result = StackWalk64
(
#if defined(_M_AMD64)
IMAGE_FILE_MACHINE_AMD64
#else
IMAGE_FILE_MACHINE_I386
#endif
,
process,
thread,
&stack,
&ctxCopy,
NULL,
SymFunctionTableAccess64,
SymGetModuleBase64,
NULL
);
if( !result ) break;
//get symbol name for address
pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
pSymbol->MaxNameLen = MAX_SYM_NAME;
SymFromAddr(process, ( ULONG64 )stack.AddrPC.Offset, &displacement, pSymbol);
line = (IMAGEHLP_LINE64 *)malloc(sizeof(IMAGEHLP_LINE64));
line->SizeOfStruct = sizeof(IMAGEHLP_LINE64);
//try to get line
if (SymGetLineFromAddr64(process, stack.AddrPC.Offset, &disp, line))
{
printf("\tat %s in %s: line: %lu: address: 0x%0X\n", pSymbol->Name, line->FileName, line->LineNumber, pSymbol->Address);
}
else
{
//failed to get line
printf("\tat %s, address 0x%0X.\n", pSymbol->Name, pSymbol->Address);
hModule = NULL;
lstrcpyA(module,"");
GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
(LPCTSTR)(stack.AddrPC.Offset), &hModule);
//at least print module name
if(hModule != NULL)GetModuleFileNameA(hModule,module,MaxNameLen);
printf ("in %s\n",module);
}
free(line);
line = NULL;
}
}
//******************************************************************************
void function2()
{
int a = 0;
int b = 0;
throw exception();
}
void function1()
{
int a = 0;
function2();
}
void function0()
{
function1();
}
int seh_filter(_EXCEPTION_POINTERS* ex)
{
printf("*** Exception 0x%x occured ***\n\n",ex->ExceptionRecord->ExceptionCode);
printStack(ex->ContextRecord);
return EXCEPTION_EXECUTE_HANDLER;
}
static void threadFunction(void *param)
{
__try
{
function0();
}
__except(seh_filter(GetExceptionInformation()))
{
printf("Exception \n");
}
}
int _tmain(int argc, _TCHAR* argv[])
{
_beginthread(threadFunction, 0, NULL);
printf("Press any key to exit.\n");
cin.get();
return 0;
}
Example output (first two entries are noise, but the rest correctly reflects functions that caused exception):
*** Exception 0xe06d7363 occured ***
at RaiseException, address 0xFD3F9E20.
in C:\Windows\system32\KERNELBASE.dll
at CxxThrowException, address 0xDBB5A520.
in C:\Windows\system32\MSVCR110D.dll
at function2 in c:\work\projects\test\test.cpp: line: 146: address: 0x3F9C6C00
at function1 in c:\work\projects\test\test.cpp: line: 153: address: 0x3F9C6CB0
at function0 in c:\work\projects\test\test.cpp: line: 158: address: 0x3F9C6CE0
at threadFunction in c:\work\projects\test\test.cpp: line: 174: address: 0x3F9C6D70
at beginthread, address 0xDBA66C60.
in C:\Windows\system32\MSVCR110D.dll
at endthread, address 0xDBA66E90.
in C:\Windows\system32\MSVCR110D.dll
at BaseThreadInitThunk, address 0x773C6520.
in C:\Windows\system32\kernel32.dll
at RtlUserThreadStart, address 0x775FC520.
in C:\Windows\SYSTEM32\ntdll.dll
Another option is to create custom exception class that captures context in constructor and use it (or derived classes) to throw exceptions:
class MyException{
public:
CONTEXT Context;
MyException(){
RtlCaptureContext(&Context);
}
};
void function2()
{
throw MyException();
}
//...
try
{
function0();
}
catch (MyException& e)
{
printf("Exception \n");
printStack(&e.Context);
}
If you wanted to capture the stack backtrace of the point where the code threw an exception, you must capture the stack backtrace in the ctor of the exception object and store it within the exception object. Hence the part calling CaptureStackBackTrace() should be moved to the constructor of the exception object, which should also provide methods to fetch it either as a vector of addresses or as a vector of symbols. This is exactly how Throwable in Java and Exception in C# operate.
Finally, please do not write:
throw new exception;
in C++, as you would in C# or Java. This is an excellent way to both produce memory leaks and to fail to catch the exceptions by type (as you are throwing pointers to these types). Rather use:
throw exception();
I'm aware that this is an old question but people (including myself) are still finding it.
do you miss the call to below?
SymInitialize(process, NULL, TRUE);
SymSetOptions(SYMOPT_LOAD_LINES);