GetThreadContext returns EBP = 0 - c++

I'm trying to get the value of another process' EBP register on windows7 64 bits.
for this I'm using GetThreadContext like this:
static CONTEXT threadContext;
memset(&threadContext, 0, sizeof(CONTEXT));
threadContext.ContextFlags = CONTEXT_FULL;
bool contextOk = GetThreadContext(threadHandle, &threadContext);
The EIP value seems ok, but EBP = 0.
I tried using also WOW64_GetThreadContext but it didn't help...
GetLastError() returns 0 so it's supposed to be ok.
I do suspend this thread with SuspendThread and It DOESN'T happen every time I sample the thread.
What could cause this?

One possible cause is that the register's value really is zero at the time you inspect it. It's a general-purpose register, so the program can set it to whatever value it wants.

Related

D3D device invalidated or destroyed prematurely

At least one user of my software has encountered a very strange crash after a Windows 10 update. This crash always happens in the same place, and it appears as if the IDirect3DDevice9 has been destroyed or invalidated in some way during a previous call.
There is nothing else in the program that would release or destroy this device prematurely, and there are no other threads that could possibly interfere. The user has said updating their video drivers did not fix the problem, and their graphics card is an Nvidia GTX 1060 6GB, so a little older but by no means a potato.
IDirect3DSurface9 *s;
HRESULT hr = m_d3dDevice->GetBackBuffer(0,0,D3DBACKBUFFER_TYPE_MONO,&s);
if(FAILED(hr)) {
...
return;
}
// crash happens here, when pushing m_d3dDevice to the stack before the call
m_d3dDevice->SetRenderTarget(0,s);
The above code crashes before calilng SetRenderTarget. The m_d3dDevice value is read successfully from this, but when the pointer is dereferenced again to get the vftable, the program crashes. Here's the disassembly:
mov eax, [edi+1Ch] ; read m_d3dDevice
push [ebp+var_E0] ; push s
push 0 ; push 0
mov ecx, [eax] ; load vftable; crashes here
push eax ; push m_d3dDevice (this)
call dword ptr [ecx+94h] ; call SetRenderTarget
The call to GetBackBuffer() completes successfully just before this point. Without a successful completion, it would bail out of the function. Nothing else in my code could possibly be destroying the device, or the object this code belongs to, during this time.
Also, I should mention that this code is in a final presentation routine, which is usually only called after other rendering steps have been done. (After SetRenderTarget(), a temporary surface that was used for all the drawing is rendered to the back buffer using a special shader for upscaling, before Present() is called.) Just prior to this code being called, the device has been confirmed to still be active via TestCooperativeLevel(), so this code will not be reached if the device is not ready to do any of this.
As far as I know this crash does not happen to every user, only to some (one confirmed, possibly two). Is it possible, even perhaps likely, that some other program on their system is the issue? I don't know why it would appear out of the blue even if so, but I have no idea why the device is destroyed/invalid when the second call happens yet perfectly valid during the first.
Update to this issue: The user who reported this was using MSI Afterburner, which apparently was the cause of this. After shutting down Afterburner, the application ran correctly. I was correct that an outside program was interfering, although it still isn't clear why the Windows 10 update impacted it. This suggests Afterburner does some DirectX hooks.

Get 32bit PEB of another process from a x64 process

I have a 64 bit process that needs to read the 32bit PEB of a Wow64 process.
I'm able to get it with NtQueryInformationProcess, but I realized that Wow64 processes have two PEBs (64 and 32 bit) and NtQueryInformationProcess returns the PEB corresponding to the bitness of the caller (64bit in my case), as #Anders commented in this solution:
How to get the Process Environment Block (PEB) from extern process?
That's my scenario: I'm trying to get the 32bit PEB of a Wow64 process, from inside a x64 process. Any suggestions that involve changing that scenario are useless. I'm also aware that this kind of solution is not recommended for production and that's not my intention.
Any ideas?
Thanks in advance.
If you read the NtQueryInterformationProcess() documentation on MSDN, there is a comment that says:
It appears that when querying a process running under wow64 in (at least) windows Vista the PebBaseAddress returned is actually for the 64-bit modules loaded under wow64. From some initial investigations I've done it appears that the PEB which pertains to 32-bit modules can be found by taking the PebBaseAddress and subtracting one page (0x1000) from its value. I have minimally confirmed this hypothesis by inspecting the process's TIB's and following their PEB pointers back to an address which, so far, has always shown to be -0x1000 from the PebBaseAddress value returned by this function.
Update: I just found this code that states the above will not work from Windows 8 onwards, but does provide an alternative solution:
#define TEB32OFFSET 0x2000
void interceptNtDll32(HANDLE hProcess)
{
THREAD_BASIC_INFORMATION tbi;
NTSTATUS ntrv;
TEB32 teb32;
void *teb32addr;
PEB_LDR_DATA32 ldrData;
PEB32 peb32;
LIST_ENTRY32 *pMark = NULL;
LDR_DATA_TABLE_ENTRY32 ldrDataTblEntry;
size_t bytes_read;
HANDLE hThread = getThreadHandle(hProcess);
/* Used to be able to get 32 bit PEB from PEB64 with 0x1000 offset but
Windows 8 changed that so we do it indirectly from the TEB */
if(!hThread)
return;
/* Get thread basic information to get 64 bit TEB */
ntrv = NtQueryInformationThread(hThread, ThreadBasicInformation, &tbi, sizeof(tbi), NULL);
if(ntrv != 0){
goto out;
}
/* Use magic to find 32 bit TEB */
teb32addr = (char *)tbi.TebBaseAddress + TEB32OFFSET; // Magic...
ntrv = NtReadVirtualMemory(hProcess, teb32addr, &teb32, sizeof(teb32), NULL);
if(ntrv != 0 || teb32.NtTib.Self != (DWORD)teb32addr){ // Verify magic...
goto out;
}
/* TEB32 has address for 32 bit PEB.*/
ntrv = NtReadVirtualMemory(hProcess, (void *)teb32.ProcessEnvironmentBlock, &peb32, sizeof(peb32), NULL);
if(ntrv != 0){
goto out;
}
...
You can use NtQueryInformationProcess
see https://learn.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-ntqueryinformationprocess#ulong_ptr
set the ProcessInformationClass to ProcessWow64Information
set a pointer to recive the ProcessInformation's value
When called the api, the ProcessInformation's value will be pebBaseAddr of the wow64 process if it's not zero

SetThreadAffinityMask Usage

i really have a hard time understanding the SetThreadAffinityMask function. Im trying to implement a timer with the QueryPerformanceCounter function but I dont understand how to get the thread affinity right. A guy on msdn posted the following code example:
void HRTimer::StartTimer(void)
{
DWORD_PTR oldmask = ::SetThreadAffinityMask(::GetCurrentThread(), 0);
::QueryPerformanceCounter(&start);
::SetThreadAffinityMask(::GetCurrentThread(), oldmask);
}
But when I adopt this code snippet the value for oldmask returned by SetThreadAffinityMask is zero. On MSDN I saw that a return value of zero means that an error occurred. I called GetLastError() and got the error code for ERROR_INVALID_PARAMETER. Now im wondering if the code snippet above isnt correct. Can someone please explain me how to use SetThreadAffinityMask correctly so that QueryPerformanceCounter is for example only called on the first CPU on the system? Or is the above example correct allthough SetThreadAffinityMask returns zero?
Thank you in advance.
The mask is a bitfield: each bit designate a processor. 0 means "no processor". It's not logic.
0x0001 : proc 1
0x0003 : proc 1 and 2
0x000F : proc 1, 2, 3, 4
...
MSDN for SetThreadAffinityMask

threading in someone else's address space

I'm building a monitor app and am having some threading issues.
I have, using a cbt hook, injected a dll in to another processes memory. I am reading the memory of the other application at certain addresses. The trouble is I was using a loop to watch the process and basically the app being watched wasn't free to carry on. So I thought put my watch process in a thread. I am using the code below to create the thread:
void readAddresses(DWORD addr)
{
LPDWORD dwThreadID;
HANDLE hThread = CreateThread(NULL,0,ThreadProc,&addr,0,dwThreadID);
}
I did try with CreateRemoteThread(...) as well and got the same error. With the thread running when it calls the ReadProcessMemory() api it fails and i am not really sure what I am doing wrong.
//going to pass in an address, dword
DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
DWORD pid;
GetWindowThreadProcessId(targetWindow,&pid);
HANDLE hProcess = ::OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION |
PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ,
FALSE, pid);
...
ReadProcessMemory(hProcess,(void *)_start, data, 255, &lpRead);
...
}
The trouble is when I call readprocessmemory I now get an access violation. What I am curious about is that is the thread operating in the same process address space as the process into which it been injected. As I said without the thread code it works fine but i need the monitor code to run in the background and i am wondering how to achieve this? Should I use create remote thread?
As Remus sais use beginthread() or beginthreadex()...
Thanks
One thing is sure: addresses to read and write are definitely not a DWORD type. From the code above, it seems that you pass an DWORD addr as the address to read from, then you start a thread to which you pass on the address of your local addr parameter. Most likely the thread proc is then attempting to read the address where the addr parameter once was in the current process on the original thread stack (a meaningless address now in any process) and the result is random (sometimes you will hit jackpot and read some innocent victim location on the remote process).
pass in the address to read as a proper address (LPVOID). DWORD cannot be right.
pass to the background thread the address you want to read, not some local stack frame garbage it cannot use
.
void readAddresses(LPVOID addr)
{
LPDWORD dwThreadID;
HANDLE hThread = CreateThread(NULL,0,myThreadProc,addr,0,dwThreadID);
}
DWORD WINAPI myThreadProc(LPVOID addr)
{
...
ReadProcessMemory (..., addr);
}

win32 : Get the state of an event object

I'm creating 3 events with the following function:
HANDLE WINAPI CreateEvent(...);
I'm waiting on all (bWaitAll is set to TRUE) event objects or a timeout with:
DWORD WINAPI WaitForMultipleObjects(...);
The return value is:
WAIT_TIMEOUT
Is there an easy way to check each event to find the one(s) that was(where) not set?
As an example :
HANDLE evt1 = ....
HANDLE evt2 = ....
HANDLE evt3 = ....
HANDLE evts[3] = ....
DWORD ret = ::WaitForMultipleObjects(3, evts, TRUE, 10000);
After 10 sec :
'ret' is WAIT_TIMEOUT.
evt1 is set
evt2 is NOT set
evt3 is set
The return value tells me "The time-out interval elapsed and the conditions specified by the bWaitAll parameter are not satisfied.", but not which one were signaled and which one were not.
Thanks,
Yes, after WaitForMultipleObjects() returned call WaitForSingleObject() for each event specifying zero timeout.
It will return WAIT_TIMEOUT for events that are not signalled and WAIT_OBJECT_0 for signalled events. Don't forget to check for WAIT_FAILED.
Surely each event state might have been changed compared to the states they had at the moment WaitFormultipleObjects() returned.
OK. Total rewrite after having the question explained to me better in the comments.
So if I'm understanding this right now, you are calling WaitForMultipleObjects with bWaitAll set to true, and when you get WAIT_TIMEOUT back from it, want to figure out which objects are holding up the works.
In that case, I'm with sharptooth, sort of. You can call WaitForSingleObject with a 0 timeout for each object. The problem with doing this is that it has side-effects for some objects. For example, if you do this on a mutex and it succeeds, you not only know it wasn't the culprit, but you now own the mutex. If that isn't what you want, you'll have to know to immediately release it.
Any apporach you take is going to be subject to race conditions. Since you are outside of the "atomic" wait call, you could go through the process and discover that now they are all ready. You could get back a set of ready/unready that isn't what you actually had inside the wait call.
Ick.
None of this work, as WaitForSingleObject() will trigger an auto-reset event even when timeout is 0.
(Contrary to what MSDN says).
If your call returns WAIT_TIMEOUT it means that NONE of the objects you waited for was signalled..