I've created project using CMake in VS. Later I've add boost and gmock usage. GMock forced me to set /MT flag on all project in solution (main exe, plugins, dll, UT).
Now I'm facing strange problem. Log4Qt is my logging library. During startup when loggers are created deep inside this library
mpTextStream = new QTextStream(stdout);
where 'stdout' during runtime goes to
/* These functions are for enabling STATIC_CPPLIB functionality */
_CRTIMP FILE * __cdecl __iob_func(void)
{
return _iob;
}
which returns NULL (only first item in this _iob array isn't NULL). Ok, I see that those entries seems to be valid as initialization of this table is
FILE _iob[_IOB_ENTRIES] = {
/* _ptr, _cnt, _base, _flag, _file, _charbuf, _bufsiz */
/* stdin (_iob[0]) */
{ _bufin, 0, _bufin, _IOREAD | _IOYOURBUF, 0, 0, _INTERNAL_BUFSIZ },
/* stdout (_iob[1]) */
{ NULL, 0, NULL, _IOWRT, 1, 0, 0 },
...
So in the result when
void __cdecl _lock_file (
FILE *pf
)
{
/*
* The way the FILE (pointed to by pf) is locked depends on whether
* it is part of _iob[] or not
*/
if ( (pf >= _iob) && (pf <= (&_iob[_IOB_ENTRIES-1])) )
{
/*
* FILE lies in _iob[] so the lock lies in _locktable[].
*/
_lock( _STREAM_LOCKS + (int)(pf - _iob) );
/* We set _IOLOCKED to indicate we locked the stream */
pf->_flag |= _IOLOCKED;
}
else
/*
* Not part of _iob[]. Therefore, *pf is a _FILEX and the
* lock field of the struct is an initialized critical
* section.
*/
EnterCriticalSection( &(((_FILEX *)pf)->lock) );
}
stdout isn't recognized as part of _iob array and standard EnterCriticalSection is run which result in 'Unhandled exception at 0x77E58DC9 (ntdll.dll) in ComputerConfShop.exe: 0xC0000005: Access violation writing location 0x00000014.'
Should I add some specific building flag? Or gmock can be easily change from /MT to /MD library? Or something other?
Related
I'm trying to create a mod loader for an 18 year old game to help me get better at c++. Right now I'm just trying to inject a dll into the same process of the mod loader. The sample dll just prints some text to the command window but doesn't. I think that the code that I have loading the entry point of the dll is not working because everything works up until I call the entry point function of my sample dll within my ModLoader.exe, and Visual Studio just throws an Access Violation. I poked through the memory viewer in debug mode within visual studio to try and see where my ModLoader program thinks the dll entry point is located within the dll but the address just points to a bunch of zeros. I recently learned the PE file format and tried to understand all the code that I wrote when I was following a tutorial on Youtube on how to do this, so forgive me for my inexperience I'm just trying to learn. The other code that I do not show is me locating and finding the target process, reading the dll binary, getting the headers from the dll, me allocating space on the target process for the dll, and finally me writing all of the section header data into the target process. I can provide any other code that y'all would like to see!
Injector.h
using ModLoader_LoadLibrary = HINSTANCE(WINAPI*)(const char* filename);
using ModLoader_GetProcAddress = UINT_PTR(WINAPI*)(HINSTANCE module, const char* procName);
using ModLoader_DllEntry = BOOL(WINAPI*)(HINSTANCE dll, DWORD reason, LPVOID reserved);
struct ModLoader_ManualMapping_Data
{
ModLoader_LoadLibrary ML_LoadLibrary; //Function pointer to the windows load library function
ModLoader_GetProcAddress ML_ProcAddress; //Function pointer to a function to be called
HINSTANCE ML_Module; //dll instance
};
Injector.cpp : Shellcode function that'll run alongside the target executable
void __stdcall Shellcode(ModLoader_ManualMapping_Data* data)
{
if (!data)
return;
BYTE* pData = reinterpret_cast<BYTE*>(data);
IMAGE_OPTIONAL_HEADER& optHeader = reinterpret_cast<IMAGE_NT_HEADERS*>(pData + reinterpret_cast<IMAGE_DOS_HEADER*>(pData)->e_lfanew)->OptionalHeader;
auto loadLibrary = data->ML_LoadLibrary;
auto procAddress = data->ML_ProcAddress;
auto dllLoad = reinterpret_cast<ModLoader_DllEntry>(pData + optHeader.AddressOfEntryPoint); //Loads entry point func from dll
BYTE* locationDelta = pData - optHeader.ImageBase; //pData = the new address | ImageBase = preferred address -> Get the difference between the two to add to every address in the relocation table
if (locationDelta) //THIS DOES NOT GET RAN
{
//Adds the delta value to all addresses within the base relocation table
}
//Import table
if (optHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size)
{
IMAGE_IMPORT_DESCRIPTOR* imgImport = reinterpret_cast<IMAGE_IMPORT_DESCRIPTOR*>(pData
+ optHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
while (imgImport->Name) //THIS DOES NOT GET RAN B\C imgImport is all zeros.
{
//Loops through import table
}
}
if (optHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size) //THIS DOES NOT GET RAN
{
//Calls the callback functions within dll
}
dllLoad(reinterpret_cast<HINSTANCE>(pData), DLL_PROCESS_ATTACH, nullptr); //PROBLEM: ACCESS VIOLATION
}
Injector.cpp : bool ManualMapping(HANDLE process, const char* dllFilepath)
-- This function is called in main.cpp.
The srcData variable is just the binary contents of the dll
ModLoader_ManualMapping_Data loadData = { 0 };
loadData.ML_LoadLibrary = LoadLibraryA;
loadData.ML_ProcAddress = reinterpret_cast<ModLoader_GetProcAddress>(GetProcAddress);
memcpy(srcData, &loadData, sizeof(loadData));
WriteProcessMemory(process, locOfDll, srcData, 0x1000, nullptr);
void* shellCodeBase = VirtualAllocEx(process, nullptr, 0x1000, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); //Allocates 0x1000 bytes in the process memory for the shellcode
WriteProcessMemory(process, shellCodeBase, Shellcode, 0x1000, nullptr); //Injects the Shellcode function into the process
HANDLE thread = nullptr;
thread = CreateRemoteThread(process, nullptr, 0, reinterpret_cast<PTHREAD_START_ROUTINE>(shellCodeBase), locOfDll, 0, nullptr); //Runs
Finally the sample dll code
#include <Windows.h>
BOOL WINAPI DllMain(HINSTANCE hModule, DWORD reason_for_call, LPVOID lpReserved)
{
switch (reason_for_call)
{
case DLL_PROCESS_ATTACH:
OutputDebugStringA("Injected!");
break;
}
return TRUE;
}
EDIT
After rewriting all the code and looking at it all day I finally figured it out. I just had to make sure that the parameters were right when I called dllLoad!
I have a non sistematic crash (R6016) when our application is about to terminate.
The application is composed of several DLL.
After a little investigation, we found the problem inside a function of mscvrt ( VS 2010) :
_ptiddata __cdecl _getptd_noexit (
void
)
{
_ptiddata ptd;
DWORD TL_LastError;
TL_LastError = GetLastError();
#ifdef _M_IX86
/*
* Initialize FlsGetValue function pointer in TLS by calling __set_flsgetvalue()
*/
if ( (ptd = (__set_flsgetvalue())(__flsindex)) == NULL ) {
#else /* _M_IX86 */
if ( (ptd = FLS_GETVALUE(__flsindex)) == NULL ) {
#endif /* _M_IX86 */
/*
* no per-thread data structure for this thread. try to create
* one.
*/
#ifdef _DEBUG
extern void * __cdecl _calloc_dbg_impl(size_t, size_t, int, const char *, int, int *);
if ((ptd = _calloc_dbg_impl(1, sizeof(struct _tiddata), _CRT_BLOCK, __FILE__, __LINE__, NULL)) != NULL) {
#else /* _DEBUG */
if ((ptd = _calloc_crt(1, sizeof(struct _tiddata))) != NULL) {
#endif /* _DEBUG */
if (FLS_SETVALUE(__flsindex, (LPVOID)ptd) ) {
/*
* Initialize of per-thread data
*/
_initptd(ptd,NULL);
ptd->_tid = GetCurrentThreadId();
ptd->_thandle = (uintptr_t)(-1);
}
else {
/*
* Return NULL to indicate failure
*/
_free_crt(ptd);
ptd = NULL;
}
}
}
SetLastError(TL_LastError);
return(ptd);
}
This function is called normally during process shutdown and normally it works.
When it doesn't work it returns NULL; analyzing the code the point of failure are:
calloc_crt returns NULL, ie it can't alloc memory
FLS_SETVALUE returns 0
FLS_SETVALUE is a macro that calls FlsSetValue. It receives a global var, __flsindex, that is the index for fiber
allocated with FlsAlloc.
__flsindex is resetted at termination of process in the ctr function of _mtterm
I think that crt is shutting down prematurely, before another DLL that use it but i don't know why.
Our program doesn't call CreateThread.
So my question is:
how dll are terminated and in which order? is it deterministic or changes from execution to execution?
how can I investigate further?
I am using Spidermonkey 1.8.5 in my application.
My application crashes when I use the debug JS library. I am building the library with the following options:
--enable-debug --disable-optimize --enable-threadsafe
crash is pointing here:
Assertion failure: (cx)->thread->data.requestDepth || (cx)->thread == (cx)->runtime->gcThread, at ../../src/jsapi.cpp
Here is the sample program
/* Include the JSAPI header file to get access to SpiderMonkey. */
#include "jsapi.h"
/* The class of the global object. */
static JSClass global_class = {
"global", JSCLASS_GLOBAL_FLAGS,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
JSCLASS_NO_OPTIONAL_MEMBERS
};
/* The error reporter callback. */
void reportError(JSContext *cx, const char *message, JSErrorReport *report)
{
fprintf(stderr, "%s:%u:%s\n",
report->filename ? report->filename : "<no filename=\"filename\">",
(unsigned int) report->lineno,
message);
}
int main(int argc, const char *argv[])
{
/* JSAPI variables. */
JSRuntime *rt;
JSContext *cx;
JSObject *global;
printf("Started\n");
/* Create a JS runtime. You always need at least one runtime per process. */
rt = JS_NewRuntime(8 * 1024 * 1024);
if (rt == NULL)
return 1;
/*
* Create a context. You always need a context per thread.
* Note that this program is not multi-threaded.
*/
cx = JS_NewContext(rt, 8192);
if (cx == NULL)
return 1;
JS_SetErrorReporter(cx, reportError);
/*
* Create the global object in a new compartment.
* You always need a global object per context.
*/
global = JS_NewCompartmentAndGlobalObject(cx, &global_class, NULL);
if (global == NULL)
return 1;
/*
* Populate the global object with the standard JavaScript
* function and object classes, such as Object, Array, Date.
*/
if (!JS_InitStandardClasses(cx, global))
return 1;
/* Your application code here. This may include JSAPI calls
* to create your own custom JavaScript objects and to run scripts.
*
* The following example code creates a literal JavaScript script,
* evaluates it, and prints the result to stdout.
*
* Errors are conventionally saved in a JSBool variable named ok.
*/
char *script = "'Hello ' + 'World!'";
jsval rval;
JSString *str;
JSBool ok;
const char *filename = "noname";
uintN lineno = 0;
ok = JS_EvaluateScript(cx, global, script, strlen(script),
filename, lineno, &rval);
if (rval == NULL | rval == JS_FALSE)
return 1;
str = JS_ValueToString(cx, rval);
printf("%s\n", JS_EncodeString(cx, str));
/* End of your application code */
/* Clean things up and shut down SpiderMonkey. */
JS_DestroyContext(cx);
JS_DestroyRuntime(rt);
JS_ShutDown();
return 0;
}
If I am building in release mode the program works fine. this problem is only with the debug mode. What am I missing here?
Insert JS_BeginRequest(cx); just before the JS_NewCompartmentAndGlobalObject call.
Insert JS_EndRequest(cx); just before the call to JS_DestroyContext.
Most JSAPI functions require a request. (I'm not sure why. The original reason for threads had to do with multithreading, but each JSRuntime is single-threaded now.)
The debug build of SpiderMonkey includes assertions that check API usage in ways that release mode can't. So you will likely see debug-only assertions again. I strongly recommend developing against a debug build, because those assertions almost always indicate real problems.
The next SpiderMonkey release is coming soon: https://bugzilla.mozilla.org/show_bug.cgi?id=735599#c54
I wrote a UNIX daemon (targeting Debian, but it shouldn't matter) and I wanted to provide some way of creating a ".pid" file, (a file which contains the process identifier of the daemon).
I searched for a way of opening a file only if it doesn't exist, but couldn't find one.
Basically, I could do something like:
if (fileexists())
{
//fail...
}
else
{
//create it with fopen() or similar
}
But as it stands, this code does not perform the task in a atomic fashion, and doing so would be dangerous, because another process might create the file during my test, and the file creation.
Do you guys have any idea on how to do that?
Thank you.
P.S: Bonus point for a solution which only involves std::streams.
man 2 open:
O_EXCL Ensure that this call creates the file: if this flag is specified in conjunction with O_CREAT, and pathname already exists, then open()
will fail. The behavior of O_EXCL is undefined if O_CREAT is not specified.
so, you could call fd = open(name, O_CREAT | O_EXCL, 0644); /* Open() is atomic. (for a reason) */
UPDATE: and you should of course OR one of the O_RDONLY, O_WRONLY, or O_RDWR flags into the flags argument.
I learned about proper daemonizing here (back in the day):
http://www.enderunix.org/docs/eng/daemon.php
It is a good read. I have since improved the locking code to eliminate race conditions on platforms that allow advisory file locking with specific regions specified.
Here is a relevant snippet from a project that I was involved in:
static int zfsfuse_do_locking(int in_child)
{
/* Ignores errors since the directory might already exist */
mkdir(LOCKDIR, 0700);
if (!in_child)
{
ASSERT(lock_fd == -1);
/*
* before the fork, we create the file, truncating it, and locking the
* first byte
*/
lock_fd = creat(LOCKFILE, S_IRUSR | S_IWUSR);
if(lock_fd == -1)
return -1;
/*
* only if we /could/ lock all of the file,
* we shall lock just the first byte; this way
* we can let the daemon child process lock the
* remainder of the file after forking
*/
if (0==lockf(lock_fd, F_TEST, 0))
return lockf(lock_fd, F_TLOCK, 1);
else
return -1;
} else
{
ASSERT(lock_fd != -1);
/*
* after the fork, we instead try to lock only the region /after/ the
* first byte; the file /must/ already exist. Only in this way can we
* prevent races with locking before or after the daemonization
*/
lock_fd = open(LOCKFILE, O_WRONLY);
if(lock_fd == -1)
return -1;
ASSERT(-1 == lockf(lock_fd, F_TEST, 0)); /* assert that parent still has the lock on the first byte */
if (-1 == lseek(lock_fd, 1, SEEK_SET))
{
perror("lseek");
return -1;
}
return lockf(lock_fd, F_TLOCK, 0);
}
}
void do_daemon(const char *pidfile)
{
chdir("/");
if (pidfile) {
struct stat dummy;
if (0 == stat(pidfile, &dummy)) {
cmn_err(CE_WARN, "%s already exists; aborting.", pidfile);
exit(1);
}
}
/*
* info gleaned from the web, notably
* http://www.enderunix.org/docs/eng/daemon.php
*
* and
*
* http://sourceware.org/git/?p=glibc.git;a=blob;f=misc/daemon.c;h=7597ce9996d5fde1c4ba622e7881cf6e821a12b4;hb=HEAD
*/
{
int forkres, devnull;
if(getppid()==1)
return; /* already a daemon */
forkres=fork();
if (forkres<0)
{ /* fork error */
cmn_err(CE_WARN, "Cannot fork (%s)", strerror(errno));
exit(1);
}
if (forkres>0)
{
int i;
/* parent */
for (i=getdtablesize();i>=0;--i)
if ((lock_fd!=i) && (ioctl_fd!=i)) /* except for the lockfile and the comm socket */
close(i); /* close all descriptors */
/* allow for airtight lockfile semantics... */
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 200000; /* 0.2 seconds */
select(0, NULL, NULL, NULL, &tv);
VERIFY(0 == close(lock_fd));
lock_fd == -1;
exit(0);
}
/* child (daemon) continues */
setsid(); /* obtain a new process group */
VERIFY(0 == chdir("/")); /* change working directory */
umask(027); /* set newly created file permissions */
devnull=open("/dev/null",O_RDWR); /* handle standard I/O */
ASSERT(-1 != devnull);
dup2(devnull, 0); /* stdin */
dup2(devnull, 1); /* stdout */
dup2(devnull, 2); /* stderr */
if (devnull>2)
close(devnull);
/*
* contrary to recommendation, do _not_ ignore SIGCHLD:
* it will break exec-ing subprocesses, e.g. for kstat mount and
* (presumably) nfs sharing!
*
* this will lead to really bad performance too
*/
signal(SIGTSTP,SIG_IGN); /* ignore tty signals */
signal(SIGTTOU,SIG_IGN);
signal(SIGTTIN,SIG_IGN);
}
if (0 != zfsfuse_do_locking(1))
{
cmn_err(CE_WARN, "Unexpected locking conflict (%s: %s)", strerror(errno), LOCKFILE);
exit(1);
}
if (pidfile) {
FILE *f = fopen(pidfile, "w");
if (!f) {
cmn_err(CE_WARN, "Error opening %s.", pidfile);
exit(1);
}
if (fprintf(f, "%d\n", getpid()) < 0) {
unlink(pidfile);
exit(1);
}
if (fclose(f) != 0) {
unlink(pidfile);
exit(1);
}
}
}
See also http://gitweb.zfs-fuse.net/?p=sehe;a=blob;f=src/zfs-fuse/util.c;h=7c9816cc895db4f65b94592eebf96d05cd2c369a;hb=refs/heads/maint
The only way I can think of is to use system level locks. See this: C++ how to check if file is in use - multi-threaded multi-process system
One way to approach this problem is to open the file for appending. If the function succeeds and the position is at 0 then you can be fairly certain this is a new file. Could still be an empty file but that scenario may not be important.
FILE* pFile = fopen(theFilePath, "a+");
if (pFile && gfetpos(pFile) == 0) {
// Either file didn't previously exist or it did and was empty
} else if (pFile) {
fclose(pFile);
}
It would appear that there's no way to do it strictly using streams.
You can, instead, use open (as mentioned above by wildplasser) and if that succeeds, proceed to open the same file as a stream. Of course, if all you're writing to the file is a PID, it is unclear why you wouldn't just write it using C-style write().
O_EXCL only excludes other processes that are attempting to open the same file using O_EXCL. This, of course, means that you never have a perfect guarantee, but if the file name/location is somewhere nobody else is likely to be opening (other than folks you know are using O_EXCL) you should be OK.
I have a CExceptionHandler class that is invoked whenever my application detects a run-time exception. For example:
if ( val == NULL )
{
TRACE(_T("Unexpected NULL in sequence."));
AfxThrowException( ERROR_INVALID_DATA );
}
AfxThrowException is very simple:
void AfxThrowException( DWORD error )
{
CExceptionHandler * pException = NULL;
if ( error == 0 )
{
error = ::GetLastError();
}
pException = new CExceptionHandler( error );
TRACE(_T("Warning: throwing CSerialException for error %d\n"), error);
THROW(pException);
}
This is the member Dump function of CExceptionHandler:
void CExceptionHandler::Dump( CDumpContext & dc ) const
{
CObject::Dump(dc);
dc << "m_dwError = " << m_dwError;
}
Higher up in my code I have the try/catch statements:
try
{
/* My app does stuff where the exception is thrown. */
}
catch( CExceptionHandler * ex )
{
afxDump << _T("Dumping exceptional data: ") << _T("\r\n");
ex->Dump( afxDump );
afxDump << _T("\r\n");
}
I would like the collected debug information to be dumped to the console. However, when the PC gets into the catch statement (verified with breakpoint), nothing happens on the console. I am using Visual Studio 2008 in Debug mode. Thoughts are appreciated. Thanks.
CDumpContext sends output to the debugger, not to the console (see OutputDebugString for more information), and if you run under the Visual Studio debugger, the output will appear in the Output window.
If you want to also send output to the console, you can configure CDumpContext to write to a CFile by passing a pointer to a CFile object in the CDumpContext constructor.
If your application is built with the 'Use Multi-Byte Character Set' configuration option, you can use CStdioFile to write to either stdout or stderr:
CStdioFile file(stdout);
CDumpContext dumpContext(&file);
ex->Dump(dumpContext);
Or, if you want to use afxDump, you can set its m_pFile member variable directly (it's declared public). For example you could put this code inside your main function:
CStdioFile file(stdout);
afxDump.m_pFile = &file;
But, this won't work if your app is built as Unicode because strings need to be converted to multi-byte to be written to stdout. To do the conversion, write a class that inherits CFile:
class CDumpFile : public CFile
{
public:
virtual void Write(const void* lpBuf, UINT nCount);
};
void CDumpFile::Write(const void* lpBuf, UINT nCount)
{
// Construct string from array of wide chars
const wchar_t* p = static_cast<const wchar_t*>(lpBuf);
UINT len = nCount / sizeof(wchar_t);
CStringW str(p, len);
CStringA astr(str); // Convert wide char to multibyte
fputs((LPCSTR)astr, stdout); // Write multibyte string to stdout
}
and use it like this:
CDumpFile file;
afxDump.m_pFile = &file;
A couple of other points about your code:
You should ensure that the exception object is deleted in the catch block. If your CExceptionHandler class inherits MFC's CException then you should call ex->Delete(). If it doesn't, you need to delete ex.
I'd advise against using the Afx prefix for own functions - you should consider this reserved for use by the MFC library, in my opinion.
I hope this helps!