Fastcall function crashes - windows

trying to call a process function using fastcall convention from my program, but got a crash everytime trying to. Have passed so much time on it and can't solve that... need some help please...
Here's all needed informations and my trying:
The picture shows the instruction context after a breakpoint when the function's program is running...
And here's my code source:
typedef void (__fastcall * MyFoo)(void * client,DWORD trash, DWORD ConstantD, DWORD objBattid, DWORD zeroParam, DWORD thousParam, float fVal,DWORD targetID);
MyFoo launchMe;
DWORD getProcessBaseAdress(DWORD ProcessID);
char *flyffServer = "insanity flyff\0";
HWND neuzWindow = NULL;
DWORD neuzProcessID = NULL;
DWORD neuzRamAdress = NULL;
HANDLE neuzHandle = NULL;
DWORD clientAdr = NULL;
int main(){
neuzWindow = FindWindowA(0,flyffServer);
//--------------------------------------
if(neuzWindow){
GetWindowThreadProcessId(neuzWindow,&neuzProcessID);
if(neuzProcessID){
neuzHandle = OpenProcess(PROCESS_ALL_ACCESS,false,neuzProcessID);
if(neuzHandle){
neuzRamAdress = getProcessBaseAdress(neuzProcessID); // Extracting Neuz's base address
if(neuzRamAdress){
launchMe = (MyFoo)((DWORD)neuzRamAdress + 0x5C400);
clientAdr = (DWORD)neuzRamAdress + 0x8D0DC0;
printf("Instruction: 0x%08X\n",launchMe);
printf("Client ADR: 0x%08X\n",clientAdr);
for(;;Sleep(100)){
//------------ init params ------------
void * client = (void*)clientAdr;
DWORD trashDX = (DWORD)0x0000000B;
DWORD msge = (DWORD)0x0000001D;
DWORD selectedBattID = 0x04D4A929;
DWORD zeroParam = (DWORD) 0x00000000;
DWORD milleParam = 0x00010000;
float speedAtt = 0.07f;
DWORD targetID = 0x0089B964;
printf("0x%08X\n0x%08X\n0x%08X\n0x%08X\n0x%08X\n0x%08X\n%f\n0x%08X\n",
client,
trashDX,
msge,
selectedBattID,
zeroParam,
thousParam,
speedAtt,
targetID
);
launchMe(client,trashDX,msge,selectedBattID,zeroParam,milleParam,speedAtt,targetID); // -> Error
scanf("%d",&trashDX); // for blocking the program
return 0;
}
}
else printf("Unable to access to Neuz's Ram Adress\n");
}
else printf("Unable to obtain neuz's handle\n");
}
else printf("Unable to detect neuz's process ID\n");
}
else printf("Unable to detect neuz's window\n");
return 0;
}
DWORD getProcessBaseAdress(DWORD ProcessID){
HANDLE hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, ProcessID);
MODULEENTRY32 me32;
me32.dwSize = sizeof(MODULEENTRY32);
Module32First(hModuleSnap,&me32);
return (DWORD) me32.modBaseAddr;
}
Thanks in advance :) ...

As said IInspectable in his comment, the problem came from accessing virtual space of another process.
Checking Windows memory management and DLL injection have solved the problem for me ... maybe anyone would face that in the futur.

Related

Problem getting USB_BANDWIDTH_INFO structure

I'm writing a Windows application in C++ reading images from an external USB cam and displaying them (which works nicely). I like to monitor the used USB bandwidth at the same time. I know that there exists a USB_BANDWIDTH_INFO structure (https://learn.microsoft.com/en-us/windows/win32/api/usbuser/ns-usbuser-usb_bandwidth_info), but I have no clue how to use it. More precisely: The structure itself is pretty clear, but how do I get/read it (didn't find any example code explaining that)?
According to the MSDN:
The USB_BANDWIDTH_INFO structure is used with the IOCTL_USB_USER_REQUEST I/O control request to retrieve information about the allocated bandwidth.
So you need to call DeviceIoControl with IOCTL_USB_USER_REQUEST.
Refer to the official example, you can find:
GetHostControllerInfo(
HANDLE hHCDev,
PUSBHOSTCONTROLLERINFO hcInfo)
{
USBUSER_CONTROLLER_INFO_0 UsbControllerInfo;
DWORD dwError = 0;
DWORD dwBytes = 0;
BOOL bSuccess = FALSE;
memset(&UsbControllerInfo, 0, sizeof(UsbControllerInfo));
// set the header and request sizes
UsbControllerInfo.Header.UsbUserRequest = USBUSER_GET_CONTROLLER_INFO_0;
UsbControllerInfo.Header.RequestBufferLength = sizeof(UsbControllerInfo);
//
// Query for the USB_CONTROLLER_INFO_0 structure
//
bSuccess = DeviceIoControl(hHCDev,
IOCTL_USB_USER_REQUEST,
&UsbControllerInfo,
sizeof(UsbControllerInfo),
&UsbControllerInfo,
sizeof(UsbControllerInfo),
&dwBytes,
NULL);
if (!bSuccess)
{
dwError = GetLastError();
OOPS();
}
else
{
hcInfo->ControllerInfo = (PUSB_CONTROLLER_INFO_0) ALLOC(sizeof(USB_CONTROLLER_INFO_0));
if(NULL == hcInfo->ControllerInfo)
{
dwError = GetLastError();
OOPS();
}
else
{
// copy the data into our USB Host Controller's info structure
memcpy(hcInfo->ControllerInfo, &UsbControllerInfo.Info0, sizeof(USB_CONTROLLER_INFO_0));
}
}
return dwError;
}
You can modify it like:
USBUSER_CONTROLLER_INFO_0 UsbControllerInfo;
UsbControllerInfo.Header.UsbUserRequest = USBUSER_GET_BANDWIDTH_INFORMATION;
UsbControllerInfo.Header.RequestBufferLength = sizeof(UsbControllerInfo);
USB_BANDWIDTH_INFO UsbBandInfo{};
DWORD dwError = 0;
DWORD dwBytes = 0;
BOOL bSuccess = FALSE;
bSuccess = DeviceIoControl(hHCDev,
IOCTL_USB_USER_REQUEST,
&UsbControllerInfo,
sizeof(UsbControllerInfo),
&UsbBandInfo,
sizeof(USB_BANDWIDTH_INFO),
&dwBytes,
NULL);

WTSIsRemoteSession always returns TRUE

I'm currently writing a Windows service, which also does something when a user logs on. There was the idea to do nothing if the logon comes from a remote computer (e.g. Remote desktop), and tried to find a way to dermine this. But following does not work - it always returns true (Windows 10 64 bit V1809) - is there something I doing wrong here?
DWORD SvcHandlerEx(DWORD controlCode, DWORD eventType, ... )
{
...
switch(controlCode)
{
case SERVICE_CONTROL_SESSIONCHANGE:
{
WTSSESSION_NOTIFICATION *pSessInfo = (WTSSESSION_NOTIFICATION *)pEvtData;
// invoke SessionChangeHandler(eventId, pSessInfo->dwSessionId)
}
...
}
...
}
...
VOID SessionChangeHandler(DWORD reason, DWORD sessionId)
{
LPWSTR *pSessionInfo = nullptr;
DWORD dataLen = 0;
BOOL isRDP = false;
if (!WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE, sessionId,
WTSIsRemoteSession, &pSessionInfo, &dataLen))
{
// Do some error handling...
return;
}
if (dataLen)
{
if (dataLen)
{
isRDP = (bool)pSessionInfo; // Always 1 (TRUE) !!!
}
WTSFreeMemory(pSessionInfo);
}
...
}
Per the documentation for WTSIsRemoteSession:
WTSIsRemoteSession
Determines whether the current session is a remote session.
The WTSQuerySessionInformation function returns a value of TRUE to indicate that the current session is a remote session, and FALSE to indicate that the current session is a local session. This value can only be used for the local machine, so the hServer parameter of the WTSQuerySessionInformation function must contain WTS_CURRENT_SERVER_HANDLE.
Windows Server 2008 and Windows Vista:  This value is not supported.
This implies that the return value of WTSQuerySessionInformation() holds the value you are looking for, and whatever memory the function may allocate, if any, is secondary and should be ignored when querying WTSIsRemoteSession, eg:
VOID SessionChangeHandler(DWORD reason, DWORD sessionId)
{
LPWSTR *pSessionInfo = nullptr;
DWORD dataLen = 0;
bool isRDP = WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE, sessionId, WTSIsRemoteSession, &pSessionInfo, &dataLen);
if ((!isRDP) && (GetLastError() != 0))
{
// Do some error handling...
return;
}
if (pSessionInfo)
WTSFreeMemory(pSessionInfo);
// use isRDP as needed...
...
}
However, if you find that isRDP is always true in this case, then the documentation is misleading and you should check the contents of the pSessionInfo buffer instead. You are setting your isRDP variable based on whether WTSQuerySessionInformation() allocates any memory at all, you are not looking at what is actually inside the data.
For instance, assuming dataLen is being set to sizeof(BOOL) on output then cast your pSessionInfo pointer to a BOOL* pointer and dereference it, eg:
VOID SessionChangeHandler(DWORD reason, DWORD sessionId)
{
LPWSTR *pSessionInfo = nullptr;
DWORD dataLen = 0;
if (!WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE, sessionId, WTSIsRemoteSession, &pSessionInfo, &dataLen))
{
// Do some error handling...
return;
}
bool isRDP = * (BOOL*) pSessionInfo;
WTSFreeMemory(pSessionInfo);
// use isRDP as needed...
...
}
Alternatively:
VOID SessionChangeHandler(DWORD reason, DWORD sessionId)
{
BOOL *isRDP = nullptr;
DWORD dataLen = 0;
if (!WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE, sessionId, WTSIsRemoteSession, (LPWSTR*)&isRDP, &dataLen))
{
// Do some error handling...
return;
}
// use isRDP as needed...
WTSFreeMemory(isRDP);
...
}

Can't find GetProcAddress in kernel32.dll export directory?

I'm trying to get the RVA of specific functions in kernel32.dll so I can use the RVA as an offset from the base address of kernel32.dll in a specified process to get the VA of the functions I need to inject my dll. I already wasn't able to find LoadLibrary but I did find LoadLibraryExA and used that instead for my dll injector however I now can't find GetProcAddress which I was going to use to locate the VA of functions in my ThreadProc function. So if I can't find it that means I'm going to have to calculate and store the VA of every function I need and put it into a structure to pass to the LPVOID lpParam parameter of ThreadProc which isn't ideal.
Here's all related functions:
void* GetFileImage(char path[])
{
HANDLE hFile = CreateFile(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);//Get a handle to the dll with read rights
if(hFile == INVALID_HANDLE_VALUE){printf("Error getting file handle: %d", (int)GetLastError());return NULL;} //Check whether or not CreateFile succeeded
HANDLE file_map = CreateFileMapping(hFile, NULL, PAGE_READONLY|SEC_IMAGE, 0, 0, "KernelMap"); //Create file map
if(file_map == INVALID_HANDLE_VALUE){printf("Error mapping file: %d", (int)GetLastError());return NULL;} //Did it succeed
LPVOID file_image = MapViewOfFile(file_map, FILE_MAP_READ, 0, 0, 0); //Map it into the virtual address space of my program
if(file_image == 0){printf("Error getting mapped view: %d", (int)GetLastError());return NULL;} //Did it succeed
return file_image; //return the base address of the image
}
DWORD RVAddress(char* image, const char* proc_name)
{
DWORD address = 0xFFFFFFFF;
PIMAGE_DOS_HEADER pDos_hdr = (PIMAGE_DOS_HEADER)image; //Get dos header
PIMAGE_NT_HEADERS pNt_hdr = (PIMAGE_NT_HEADERS)(image+pDos_hdr->e_lfanew); //Get PE header by using the offset in dos header + the base address of the file image
IMAGE_OPTIONAL_HEADER opt_hdr = pNt_hdr->OptionalHeader; //Get the optional header
IMAGE_DATA_DIRECTORY exp_entry = opt_hdr.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
PIMAGE_EXPORT_DIRECTORY pExp_dir = (PIMAGE_EXPORT_DIRECTORY)(image+exp_entry.VirtualAddress); //Get a pointer to the export directory
void** func_table = (void**)(image+pExp_dir->AddressOfFunctions); //Get an array of pointers to the functions
WORD* ord_table = (WORD*)(image+pExp_dir->AddressOfNameOrdinals); //Get an array of ordinals
BYTE** name_table = (BYTE**)(image+pExp_dir->AddressOfNames); //Get an array of function names
for(int i=0;i<pExp_dir->NumberOfNames;i++) //until i is 1 less than how many names there are to iterate through elements
{
printf("%s ", (BYTE*)image+(DWORD)(intptr_t)name_table[i]); //print the name of each function iterated through, I went back and read through these names and didn't see GetProcAddress anywhere
if(strcmp(proc_name, (const char*)(BYTE*)image+(DWORD)(intptr_t)name_table[i]) == 0) //Is it the function we're looking for?
{
address = (DWORD)(intptr_t)func_table[ord_table[i]];//If so convert the address of the function into a DWORD(hexadecimal)
system("CLS"); //Clear the screen
return address; //return the address of the function
}
}
return (DWORD)0; //Other wise return 0
}
DWORD GetRemoteFunctionAddress(DWORD dwPid, char* kernel_path, char* function_name)
{
HANDLE hSnapshot = INVALID_HANDLE_VALUE;
MODULEENTRY32 me32;
me32.dwSize = sizeof(MODULEENTRY32);
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE|TH32CS_SNAPMODULE32, dwPid); //Get a snapshot of all the modules in the program(64 and 32 bit, 32 since kernel is 32)
if(hSnapshot == INVALID_HANDLE_VALUE){printf("Snapshot failed");return 0;} //Snapshot not created
if(!(Module32First(hSnapshot, &me32))) //Don't care about it because it will be the exe of the process
{
printf("Mod32First failed");
return 0;
}
while(Module32Next(hSnapshot, &me32)) //Iterate through until...
{
if(me32.szModule == "kernel32.dll"||me32.szModule == "KERNEL32.DLL") //we find kernel32.dll
{
CloseHandle(hSnapshot);
break;
}
}
printf("\nBase address: 0x%08X\n", (DWORD)(intptr_t)me32.modBaseAddr); //Used this for CheatEngine
DWORD RVA = (DWORD_PTR)RVAddress((char*)GetFileImage(kernel_path), function_name); //Get the relative virtual address of the function
DWORD Load = (DWORD_PTR)me32.modBaseAddr+(DWORD_PTR)RVA; //Add the base address of kernel32.dll and the RVA of the function to get a DWORD representation of the address of the function in the remote process
return Load; //return the address of the function in the remote process
}
Any help would be much appreciated.
if(me32.szModule == "kernel32.dll"||me32.szModule == "KERNEL32.DLL")
You can't use == on char arrays, you have to use stricmp
Instead of all this you can just use:
GetProcAddress(GetModuleHandle("KERNEL32.DLL"), "LoadLibraryA")
This will give you the absolute address at runtime

Win32 GUARD Memory : How can I use PAGE_GUARD to implement stack

I'm writing a tiny byte-code, interpreted language (or framework? vm?). I know Windows use PAGE_GUARD on stack, and I want to use this.
First, I reserve virtual memory and do MEM_COMMIT/PAGE_GUARD on one page.
pStack->end = VirtualAlloc(NULL, MaxSize, MEM_RESERVE, PAGE_READWRITE);
if (pStack->end != NULL)
{
pStack->bp = pStack->sp = pStack->base = pStack->end + MaxSize;
if (VirtualAlloc(pStack->base - PageSize, PageSize, MEM_COMMIT, PAGE_READWRITE | PAGE_GUARD) != NULL)
(I know I should commit (non PAGE_GUARD) one page, but it's for testing PAGE_GUARD.)
and I write __except as follows:
__except (StackOnSEHExcept(GetExceptionInformation())) {}
/* A */
...
DWORD StackOnSEHExcept(PEXCEPTION_POINTERS exc)
{
if (exc->ExceptionRecord->ExceptionCode == STATUS_GUARD_PAGE_VIOLATION)
{
return EXCEPTION_CONTINUE_EXECUTION;
}
else
{
return EXCEPTION_CONTINUE_SEARCH;
}
}
(I also know I should commit/guard the next page, but it's for testing, too.)
When I touch memory of stack, STATUS_GUARD_PAGE_VIOLATION is occured. but after that, /* A */ is run;
Doesn't Windows unmark PAGE_GUARD after exception occur? and why doesn't this code work well?
And, I don't know how to do this part: (I also know I should commit/guard the next page, but it's for testing, too.). How can I do? I think I should 1. get guarded-page's address 2. commit/guard the next page, but I don't know how to do 1.
edit: I know how to do 1. the guarded address is here:
exc->ExceptionRecord->ExceptionInformation[1]
Thanks for all your help!
Doesn't Windows unmark PAGE_GUARD after exception occur?
http://msdn.microsoft.com/en-us/library/windows/desktop/aa366786(v=vs.85).aspx
... Pages in the region become guard pages. Any attempt to access a guard page causes the system to raise a STATUS_GUARD_PAGE_VIOLATION exception and turn off the guard page status. Guard pages thus act as a one-time access alarm.
Try this:
DWORD OnSEH()
{
::OutputDebugString( L"SEH!\n" );
return (DWORD) EXCEPTION_CONTINUE_EXECUTION;
}
static void Test()
{
const DWORD pageSize = 4096;
void* baseAddr = ::VirtualAlloc(NULL, pageSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE );
DWORD oldAttr = 0;
void* protectedAddr = baseAddr;
BOOL ok = ::VirtualProtect( protectedAddr, pageSize, PAGE_READWRITE | PAGE_GUARD, &oldAttr );
if( !ok ) {
int lastError = ::GetLastError(); lastError;
return;
}
::OutputDebugString( L"Reading the guarded page\n" );
__try {
int* testAddr = static_cast<int*>( protectedAddr );
int value = *testAddr; value;
::OutputDebugString( L"Continue execution\n" );
}
__except( OnSEH() ) {}

How to get information from VS_VERSION_INFO inside ActiveX control

Is there a way to extract information from VS_VERSION_INFO (e.g. FILEVERSION) inside the same application?
I know, you probably thinking in a path of:
1. GetModuleFileName(...)
2. GetFileVersionInfoSize(...)
3. GetFileVersionInfo(...)
4. VerQueryValue(...)
BUT! There is a "twist": I need to make activex control to extract it's own version. So GetModuleFileName would not return the correct filename, it will be parent application name, so the version info will be from parent application too, not the activex control.
Any ideas?
Here is the code which eventiuly worked for me (and Yes, it is for MFC ActiveX control):
CString modFilename;
if(GetModuleFileName(AfxGetInstanceHandle(), modFilename.GetBuffer(MAX_PATH), MAX_PATH) > 0)
{
modFilename.ReleaseBuffer(MAX_PATH);
DWORD dwHandle = 0;
DWORD dwSize = GetFileVersionInfoSize(modFilename, &dwHandle);
if(dwSize > 0)
{
LPBYTE lpInfo = new BYTE[dwSize];
ZeroMemory(lpInfo, dwSize);
if(GetFileVersionInfo(modFilename, 0, dwSize, lpInfo))
{
//// Use the version information block to obtain the FILEVERSION.
//// This will extract language specific part of versio resources. 040904E4 is English(US) locale,
//// it should match to your project
//UINT valLen = MAX_PATH;
//LPVOID valPtr = NULL;
//if(::VerQueryValue(lpInfo,
// TEXT("\\StringFileInfo\\040904E4\\FileVersion"),
// &valPtr,
// &valLen))
//{
// CString valStr((LPCTSTR)valPtr);
// AfxMessageBox(valStr);
//}
//// This will extract so called FIXED portion of the version info
UINT valLen = MAX_PATH;
LPVOID valPtr = NULL;
if(::VerQueryValue(lpInfo,
TEXT("\\"),
&valPtr,
&valLen))
{
VS_FIXEDFILEINFO* pFinfo = (VS_FIXEDFILEINFO*)valPtr;
// convert to text
CString valStr;
valStr.Format(_T("%d.%d.%d.%d"),
(pFinfo->dwFileVersionMS >> 16) & 0xFFFF,
(pFinfo->dwFileVersionMS) & 0xFFFF,
(pFinfo->dwFileVersionLS >> 16) & 0xFFFF,
(pFinfo->dwFileVersionLS) & 0xFFFF
);
AfxMessageBox(valStr);
}
}
delete[] lpInfo;
}
}
At step 1 you can call GetModuleFileName and pass in the hModule of your DLL. You get the hModule in DllMain():
extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
DWORD length = ::GetModuleFileName(hInstance, fullFilename, MAX_PATH);
// ...
}
}

Resources