I have two Libraries: IDA and XIDA.
XIDA handles the event loop, and there is for each application/process, one single event loop.
And these libraries are "connected" via an callback function.
This is working with events inside one single app/process...
Now I noticed that I could send an event from one app to an other. What it needs was a window handle from another app. So I coded a DBus message, with what I can receive one...
This is working too, but it looks like that the receiver of XSendEvent() can only use functions and its parameters, no member variables!
In the hpp:
Window mSection;
Window Section(){
return 0; // This is working
}
Window Section_A(){
return this->mSection; // This raises a memory access error
}
int CheckEvents( IDA_A *vIDA_A, XEvent vEvent);
static int Section_EventCallback(void* this_ptr, XEvent vEvent){
IDA_A* nIDA_A = NULL;
int nRet = 1;
try{
nIDA_A = static_cast < IDA_A* > (this_ptr);
} catch (...) { return 0; }
cout << "TEST " << nIDA_A->Section() << endl; // This is working, also with any other function
cout << "TEST " << nIDA_A->mSection << endl; // This raises a memory access error, also with any other member variable
cout << "TEST " << nIDA_A->Section_A() << endl; // This also raises a memory access error
nRet = nIDA_A->CheckEvents(nIDA_A, vEvent);
nIDA_A = NULL;
return nRet;
}
In the cpp:
int IDA_A::CheckEvents(IDA_A *vIDA_A, XEvent vEvent) {
Window nWindow = vEvent.xany.window;
cout << "TEST " << " -- " << nWindow << endl; // This is working
cout << "TEST " << " -- " << this->mSection << endl; // This raises a memory access error
return 1;
}
What does it needs to use also member variables?
Regards
Earlybite
------------------------ EDIT: ----------------------------
This is the part of XIDA where XSendEvents() arrives (after calling from inside the event loop):
int XIDA_A::Send_To_Callback(XEvent vEvent){
for(int i = 0; i < (int) this->mVecEvCallback.size(); i++){
if( *this->mVecEvCallback[i].pWindow == vEvent.xany.window ){
if( vEvent.type == ClientMessage ) {
cout << "THIS XIDA CLIENT " << this->mIdent << endl;
}
s_EventCallback nEvCallback;
nEvCallback = this->mVecEvCallback[i];
nEvCallback.Callback (nEvCallback.this_Ptr, vEvent);
return 1;
}
}
return 0;
}
And to this point, it is working, also member variables. But nevermore in IDA, where the Callback is going to.
But it is the same process!
And e.g. with DBus it is working...
I really would like to know the reason!
SOLVED.
I found the error...
This
cIDAMessage nMsg;
nMsg.Msg_Type = IDAMsg_EventCallback;
nMsg.Lng_Send[0] = 0;
nMsg.Para_Void[0] = (void*) &this->mSection;
nMsg.Para_ThisPtr = (void*) this;
nMsg.Para_CallbackPtr = (void*) &this->Section_EventCallback;
this->XIDA_Callback(this->mXIDA_A_Ptr, &nMsg);
is a part of the init.
And I had forgotten to set
nMsg.Para_ThisPtr = (void*) this;
But what I still do not understand...
static int Section_EventCallback(void* this_ptr, XEvent vEvent){
IDA_A* nIDA_A = NULL;
int nRet = 1;
try{
nIDA_A = static_cast < IDA_A* > (this_ptr);
} catch (...) { return 0; }
nRet = nIDA_A->CheckEvents(nIDA_A, vEvent);
nIDA_A = NULL;
return nRet;
}
Here comes/came the pointer with NULL.
Why wasn't nIDA_A not NULL, or why wasn't there raised an error, because static_cast cannot cast with NULL?
And why were functions working, but not member variables?
You know what I mean?
Related
i'm trying to make a little program to my university that can change values in the memory of another process. With the exact address value that the Cheat Engine give me i can do this, but not ever the value is the same then my problem is with the memory pointers. In the following image i has the every offset that i found in the pointer scan map:
I already make a program but it not work and ever gives me 299 error code, i Run it as administrator. The code is the following:
#include <iostream>
#include <Windows.h>
#include <Psapi.h>
#include <TlHelp32.h>
#include <queue>
using namespace std;
int main() {
PROCESSENTRY32 pEntry;
pEntry.dwSize = sizeof(PROCESSENTRY32);
// Snapshot to list all process
HANDLE pHandlers = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
if (pHandlers == NULL) {
cout << "Error 1";
return 1;
}
// Listing process
if (Process32First(pHandlers, &pEntry)) {
while (Process32Next(pHandlers, &pEntry)) {
// Convert value to string
wstring wstr(pEntry.szExeFile);
string str(wstr.begin(), wstr.end());
// Check if is the process that i wan't
if (str == "Playgroundd.exe") {
MODULEENTRY32 mEntry;
mEntry.dwSize = sizeof(MODULEENTRY32);
// Snapshot to list all modules inside process
HANDLE mHandlers = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pEntry.th32ProcessID);
if (mHandlers == NULL) {
cout << "Error 2";
return 1;
}
// Usually the first process is the main module
if (Module32First(mHandlers, &mEntry)) {
// Convert the name to string
wstring wstrr(mEntry.szExePath);
string strr(wstrr.begin(), wstrr.end());
if (strr.find("Playgroundd.exe")) {
// Get the base address of module
DWORD moduleBaseAddress = (DWORD)mEntry.modBaseAddr;
// Append initial value
moduleBaseAddress += (DWORD)0x000000E8;
// Offsets defined
DWORD offsets[] = {0x88,0x98,0x90,0x20,0x10,0x48,0x904};
// Open process with the right process id
cout << "process id: " << pEntry.th32ProcessID << endl << endl;
HANDLE processHandler = OpenProcess(PROCESS_ALL_ACCESS, 0, pEntry.th32ProcessID);
if (processHandler == NULL) {
cout << "Can't open the process";
return 1;
}
// Sum offsets
for (int i = 0; i < 7;i++) {
moduleBaseAddress += offsets[i];
}
int receive = 0;
size_t bytesRead = 0;
bool resultStatus = ReadProcessMemory(processHandler,
(LPCVOID)moduleBaseAddress, &receive, sizeof(receive), &bytesRead);
cout << "result status :" << resultStatus << endl;
cout << "Received : " << receive << endl;
cout << "Bytes read : " << bytesRead << endl;
cout << "Possible error code : " << GetLastError() << endl;
}
else {
cout << "Can't find module";
return 1;
}
}
}
}
}
};
This is the output of the above program, the error code can be ignored if the result status be non-zero
result status :0
Received : 0
Bytes read : 0
Possible error code : 299
What i am doing wrong?
As pointed by the comment above, your calculation of the target address is questionable.
Your use of GetLastError is unsafe - you should call it immediately after FAILED call to ReadProcessMemory. However, in this case, cout << ... doesn't change that code, so you are OK.
According to docs
ERROR_PARTIAL_COPY
299 (0x12B)
Only part of a ReadProcessMemory or WriteProcessMemory request was completed.
And this post states
ReadProcessMemory would return FALSE and GetLastError would return ERROR_PARTIAL_COPY when the copy hits a page fault.
So I would like to use the DLL that I created, and I have this really weird warning I didn't see anyone has this one. I checked if LoadLibray returns "NULL", and this is not the case.
typedef DATA_BLOB(*encryption_decryption)(DATA_BLOB, bool*);
HINSTANCE dll_file = LoadLibrary(L"dllForEncryptionNDecryptionn.dll");
if (dll_file != NULL) {
cout << "Library loaded!" << endl;
}
else {
failed();
}
encryption_decryption encryption = (encryption_decryption)GetProcAddress(dll_file,"encryption");
if(encryption != NULL)
{
cout << "Workded!" << endl;
}
else
{
failed();
}
void failed() {
cout << GetLastError() << endl;
cout << "Faild!" << endl;
}
Warning at the 8th line: "'dll_file' could be '0': this does not adhere to the specification for the function 'GetProcAddress'."
Everything works, it doesn't write any errors when I run it.
If anything goes wrong in LoadLibrary you call failed() that prints the error code and returns.
HINSTANCE dll_file = LoadLibrary(L"dllForEncryptionNDecryptionn.dll");
if (dll_file != NULL) {
cout << "Library loaded!" << endl;
}
else {
failed(); // returns even when dll_file is NULL
}
// so, here you don't know if it's NULL or a valid handle which is why you get the warning
encryption_decryption encryption = (encryption_decryption)GetProcAddress(dll_file,"encryption");
If LoadLibrary fails, you shold not use that dll_file to call GetProcAddress.
encryption_decryption encryption = nullptr;
HINSTANCE dll_file = LoadLibrary(L"dllForEncryptionNDecryptionn.dll");
if(dll_file) {
encryption_decryption encryption =
(encryption_decryption)GetProcAddress(dll_file,"encryption");
} else {
// do NOT call GetProcAddress
}
if(encryption) {
// function successfully loaded
}
I'm learning StackWalk API provided by "DbgHelp" in Windows 7. I wrote an exception filter that uses StackWalk64. The intention is to back trace at most 50 lines with function name and line number. "StackWalk64" iterates through each stack frame. The address(AddrPC) retrieved from Stack Frame is used in "SymGetSymFromAddr64" and "SymGetLineFromAddr64" to retrieve Symbol name and Line number respectively. But, though "SymGetSymFromAddr64" works successfully, "SymGetLineFromAddr64" fails. The Last Error returned is 487. How can the address work successfully for the former but not for the latter?
Am I missing something? Any Help?
LONG WINAPI TestStackWalker (EXCEPTION_POINTERS* lpFilter)
{
STACKFRAME64 st;
CONTEXT cc;
HANDLE hProcess = ::GetCurrentProcess();
HANDLE hThread = ::GetCurrentThread();
vector<IMAGEHLP_SYMBOL64> vectSymbs(50);
vector<IMAGEHLP_LINE64> vectLines(50);
if (!SymInitialize(hProcess, NULL, TRUE))
{
cout << "Issue with SymInitialize ! " << ::GetLastError() << endl;
return 1;
}
cc = *(lpFilter->ContextRecord);
printContext(cc);
::ZeroMemory(&st, sizeof(st));
st.AddrStack.Mode = AddrModeFlat;
st.AddrStack.Offset = cc.Esp;
st.AddrFrame.Mode = AddrModeFlat;
st.AddrFrame.Offset = cc.Ebp;
st.AddrPC.Mode = AddrModeFlat;
st.AddrPC.Offset = cc.Eip;
for (int i = 0; i < 50; i++)
{
if (!::StackWalk64(IMAGE_FILE_MACHINE_I386,
hProcess,
hThread,
&st,
&cc,
NULL,
SymFunctionTableAccess64,
SymGetModuleBase64,
NULL))
{
cout << "Issue with StackWalkFailed: " << ::GetLastError () <<endl;
return 1;
}
if (st.AddrReturn.Offset == st.AddrPC.Offset)
{
cout << "i think it's done!" << endl;
break;
}
if (st.AddrPC.Offset != 0)
{
vectSymbs[i].SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
vectSymbs[i].MaxNameLength = 1024;
if (!SymGetSymFromAddr64 (hProcess, st.AddrPC.Offset, 0, &vectSymbs[i]))
{
cout << "Issue with Getting Symbol From Address " << ::GetLastError() << endl;
break;
}
SymSetOptions(SYMOPT_LOAD_LINES);
vectLines[i].SizeOfStruct = sizeof(IMAGEHLP_LINE64);
if (!SymGetLineFromAddr64 (hProcess, st.AddrPC.Offset, 0, &vectLines[i]))
{
cout << "Issue with Getting Line from Address " << ::GetLastError() << endl;
break;
}
cout << vectSymbs[i].Name << " at " << vectLines[i].LineNumber <<endl;
}
if (st.AddrReturn.Offset == 0)
{
cout << "seems finished " << endl;
break;
}
}
return 1;
}
The pdwDisplacement parameter is not optional:
DWORD dis;
if (!SymGetLineFromAddr64 (hProcess, st.AddrPC.Offset, &dis, &vectLines[i]))
{
cout << "Issue with Getting Line from Address " << ::GetLastError() << endl;
break;
}
I had the same problem. My symbols were on a symbol server. The solution was to put symsrv.dll (from the Windows SDK) next to dbghelp.dll, so it can be loaded. Everything worked after that. In practice, the solution was to distribute both dbghelp.dll and symsrv.dll with my application (together with dbgcore.dll and srcsrv.dll). See the Modules list in Visual Studio, to verify that both symsrv.dll and dbghelp.dll are being loaded from where you expect.
More info here:
https://learn.microsoft.com/en-us/windows/desktop/Debug/using-symsrv
(See "Installation" section)
https://learn.microsoft.com/en-us/windows/desktop/Debug/dbghelp-versions (regarding obtaining and distributing those dlls)
I am trying to get the names of a processes handle. I iterate trough a list of all handles and try to get the name like this:
void SystemHandle::GetHandleName()
{
HANDLE hFake;
char* objectName = NULL;
if (NT_SUCCESS(DuplicateHandle(this->process, this->GetNativeHandle(), GetCurrentProcess(), &hFake, 0, FALSE, DUPLICATE_SAME_ACCESS)))
{
POBJECT_TYPE_INFORMATION typeInfo = (POBJECT_TYPE_INFORMATION)new BYTE[0x1000];
PUNICODE_STRING nameInfo = (PUNICODE_STRING)new BYTE[0x1000];
DWORD read;
NTSTATUS status = NtQueryObject(hFake, ObjectTypeInformation, typeInfo, 0x1000, &read);
std::cout << "NtQueryObject: " << status << ", Success: " << NT_SUCCESS(status) << "\n";
objectName = new char[nameInfo->Length];
if (NT_SUCCESS(status) && nameInfo->Length > 0)
{
std::cout << "nameInfo length: " << nameInfo->Length << "\n";
std::cout << "objectName size: " << sizeof(objectName) << "\n";
std::cout << "nameInfo buffer: " << sizeof(nameInfo->Buffer) << "\n";
WideToChar(objectName, nameInfo->Buffer);
strcpy_s(this->handleName, objectName);
}
delete nameInfo;
delete typeInfo;
}
if (hFake) CloseHandle(hFake);
}
void WideToChar(char* Dest, const WCHAR* Source)
{
int i = 0;
// get each char from Source and put it in Dest
while(Source[i] != '\0')
{
Dest[i] = (CHAR)Source[i];
++i;
}
Dest[i] = '\0'; // create the end
}
My problem begins at WideToChar(objectName, nameInfo->Buffer); when I get to while(Source[i] != '\0'). I will then get the following error :
Unhandled exception at 0x00406CE5 in application.
exe: 0xC0000005: Access violation reading location 0xBAADF00D.
You allocate memory for the nameInfo variable, but do not initialize it. So when you try to use it, nameInfo->Buffer contains 0xBAADF00D - Microsoft magic number for uninitialized heap memory. Then you get access violation. You also should use WideCharToMultibyte function for string conversion.
wrap
while(Source[i] != '\0')
{
Dest[i] = (CHAR)Source[i];
++i;
}
inside an if condition:
if(Source != NULL){
}
I'm modifying the stock quoter example from the wustl CORBA release. The assignment is to implement a reply handler for the StockFactory class that handles calls to get_stock()
Here's my FactoryHandler implementation:
FactoryHandler_i.h:
#ifndef TAO_TUTORIALS_QUOTER_AMI_CLIENT_FACTORYHANDLER_I_H
#define TAO_TUTORIALS_QUOTER_AMI_CLIENT_FACTORYHANDLER_I_H
#include "QuoterS.h"
class Stock_Factory_Handler_i : public POA_Quoter::AMI_Stock_FactoryHandler
{
public:
Stock_Factory_Handler_i (int *response_count, ::Quoter::Stock_var& result);
void get_stock (::Quoter::Stock_ptr ami_return_val);
void get_stock_excep (::Messaging::ExceptionHolder * excep_holder);
private:
int *response_count_;
::Quoter::Stock_var& result_;
};
#endif /* TAO_TUTORIALS_QUOTER_AMI_CLIENT_HANDLER_I_H */
FactoryHandler_i.cpp:
#include "FactoryHandler_i.h"
#include "ace/streams.h"
Stock_Factory_Handler_i::
Stock_Factory_Handler_i (int *response_count, ::Quoter::Stock_var& result)
: response_count_ (response_count), result_ (result)
{
}
void
Stock_Factory_Handler_i::get_stock (::Quoter::Stock_ptr ami_return_val)
{
cout << "storing result" << endl;
result_ = ami_return_val;
(*this->response_count_)++;
}
void
Stock_Factory_Handler_i::get_stock_excep (::Messaging::ExceptionHolder * excep_holder)
{
// We ignore the exception, but this counts as a response, otherwise
// the application would not finish.
cerr << "Exception raised while getting stock"
<< endl;
(*this->response_count_)++;
}
And the client.cpp, from just before the part where changes have been made:
// ...
// Create and activate the handler...
int response_count = 0;
Single_Query_Stock_Handler_i handler_i (&response_count);
Quoter::AMI_Single_Query_StockHandler_var handler =
handler_i._this ();
// Create and activate the factory handler...
Quoter::Stock_var result;
Stock_Factory_Handler_i factory_handler_i (&response_count, result);
Quoter::AMI_Stock_FactoryHandler_var factory_handler =
factory_handler_i._this();
// Send all the requests, careful with error handling
int request_count = 0;
for (int i = 2; i != argc+1; ++i) {
try {
// Get the stock object
cout << "looking up stock symbol " << argv[i] << endl;
factory->sendc_get_stock (factory_handler.in (), argv[i]);
sleep(3); // wait for a response
cout << "converting result" << endl;
Quoter::Single_Query_Stock_var stock =
Quoter::Single_Query_Stock::_narrow (result.in ());
cout << "checking result" << endl;
CORBA::Any any;
any <<= stock;
CORBA::TypeCode_var tc = any.type();
cout << tc->kind() << endl;
if (CORBA::is_nil (stock.in ())) {
cerr << "Cannot get single query interface for <"
<< argv[i] << ">" << endl;
continue;
}
cout << "reading result" << endl;
stock->sendc_get_price_and_names (handler.in ());
request_count++;
}
catch (Quoter::Invalid_Stock_Symbol &) {
cerr << "Invalid stock symbol <"
<< argv[i] << ">" << endl;
}
}
while (response_count < 2 * request_count // multiply by 2 because both handlers increment response_count
&& orb->work_pending ()) {
orb->perform_work ();
}
// ...
When running the client, the output is:
looking up stock symbol MSFT
converting result
checking result
14
Cannot get single query interface for <MSFT>
(The 14 is the typecode for Stock, that's only for debugging)
Notably missing from the above is the "storing result" message that's supposed to be printed in the FactoryHandler's get_stock() callback method. I'm at a loss as to why, since the sendc_get_stock() method doesn't produce any (immediate) errors and is basically just a copy of the StockHandler's code, and from there it's the responsibility of the AMI/ORB interface to make the callback. But the original example (with a StockHandler only) works fine.
What am I doing wrong (and how do I fix it)?
EDIT: another bit of information: on the server side, StockFactory's get_stock() method does get called.
Sorry, I've no aswer for you. But a hint, ask your question at TOA's maling list at http://www.cs.wustl.edu/~schmidt/ACE-mail.html
HTH
I think that your problem is that work_pending returns true only if the ORB has immediate work to do, so it returns false in the time after your client sent his request and before the server sends his reply.
To validate that, simply remove the && orb->work_pending() condition from the loop, and use the version of perform_work that takes a timeout argument.