get processor architecture in MQL - winapi

i use GetNativeSystemInfo from windows api but when i use structure like microsoft i can not get parameter correctly
at the first i use this structure:
struct _SYSTEM_INFO {
union DUMMYUNIONNAME {
int dwOemId;
struct DUMMYSTRUCTNAME {
int wProcessorArchitecture;
int wReserved;
};
};
int dwPageSize;
int lpMinimumApplicationAddress;
int lpMaximumApplicationAddress;
int dwActiveProcessorMask;
int dwNumberOfProcessors;
int dwProcessorType;
int dwAllocationGranularity;
int wProcessorLevel;
int wProcessorRevision;
};
but i can not access to wProcessorArchitecture parameter.
also i have trying to edit structucture like this :
struct _SYSTEM_INFO
{
int dwOemId;
uint wProcessorArchitecture;
ulong wReserved;
int dwPageSize;
ulong lpMinimumApplicationAddress;
ulong lpMaximumApplicationAddress;
ulong dwActiveProcessorMask;
int dwNumberOfProcessors;
int dwProcessorType;
int dwAllocationGranularity;
ulong wProcessorLevel;
ulong wProcessorRevision;
};
now, when i get wProcessorArchitecture parameter, it return 4096, but microsoft msdn says that it return parameter like this :
9
5
12
6
0
can anyone help me?
this is my entire code in MQL5:
struct _SYSTEM_INFO
{
uint dwOemId;
uint wProcessorArchitecture;
ulong wReserved;
uint dwPageSize;
ulong lpMinimumApplicationAddress;
ulong lpMaximumApplicationAddress;
ulong dwActiveProcessorMask;
uint dwNumberOfProcessors;
uint dwProcessorType;
uint dwAllocationGranularity;
ulong wProcessorLevel;
ulong wProcessorRevision;
};
#import "kernel32.dll"
void GetNativeSystemInfo(_SYSTEM_INFO &lpSystemInfo);
#import
int OnInit()
{
_SYSTEM_INFO hos;
GetNativeSystemInfo(hos);
Alert(hos.wProcessorArchitecture);
}

Try the following:
struct _SYSTEM_INFO
{
uint wProcessorArchitecture;
uint wReserved;
uint dwPageSize;
ulong lpMinimumApplicationAddress;
ulong lpMaximumApplicationAddress;
ulong dwActiveProcessorMask;
uint dwNumberOfProcessors;
uint dwProcessorType;
uint dwAllocationGranularity;
uint wProcessorLevel;
uint wProcessorRevision;
};
#import "kernel32.dll"
void GetNativeSystemInfo(_SYSTEM_INFO &lpSystemInfo);
#import
int OnInit()
{
_SYSTEM_INFO hos;
GetNativeSystemInfo(hos);
Alert(hos.wProcessorArchitecture);
}

Related

Marshalling struct double pointer in C#

I am trying to marshal libnl's nla_parse call into C#.
iw's nla_parse extern signature is:
extern int nla_parse(struct nlattr **, int, struct nlattr *, int, struct nla_policy *);
I believe my problem is in correctly marshaling the tb nlattr double pointer (**).
The relevant C# extern signatures are (am omitting the DllImport clause for brevity - the calls work and return results)
public static extern IntPtr nlmsg_data(IntPtr nlh);
public static extern IntPtr nlmsg_hdr(IntPtr n);
public static extern int nla_parse(IntPtr tb, int maxtype, IntPtr head, int len, IntPtr policy);
My C# marshal call looks like
[StructLayout(LayoutKind.Sequential)]
public struct nlattr
{
public ushort nla_len;
public ushort nla_type;
}
var NL80211_ATTR_MAX = 305;
var nlAttrStructSize = Marshal.SizeOf<nlattr>();
var nlAttrStructArrayPtr = Marshal.AllocHGlobal(nlAttrStructSize * (NL80211_ATTR_MAX + 1));
var nlMsgHeaderPtr = NetlinkDemo.nlmsg_hdr(msg);
var gnlMsgHeaderPtr = NetlinkDemo.nlmsg_data(nlMsgHeaderPtr);
var gnlMsgAttrDataHeaderPtr = NetlinkDemo.genlmsg_attrdata(gnlMsgHeaderPtr, 0);
var returnCode = NetlinkDemo.nla_parse(nlAttrStructArrayPtr, NL80211_ATTR_MAX, gnlMsgAttrDataHeaderPtr, gnlMsgAttrLength, IntPtr.Zero);
I keep getting malloc(): memory corruption. Are my marshal mappings correct, and my problem is either my msg input pointer or any of the fields in any of the subsequent pointers that work as input to nla_parse ? Or this is not the way to marshal a struct double pointer ?

How to get current process's EPROCESS address in windows x64?

As we all know,we can get eprocess address in win32 using the code below.
And this code works in user mode(ring 3).
#include <stdio.h>
#include <windows.h>
#define alloc(a) VirtualAlloc(0,a,MEM_COMMIT|MEM_RESERVE,PAGE_READWRITE)
#define freea(a) VirtualFree(a,0,MEM_RELEASE)
typedef struct {
PVOID Unknown1;
PVOID Unknown2;
PVOID Base;
ULONG Size;
ULONG Flags;
USHORT Index;
USHORT NameLength;
USHORT LoadCount;
USHORT PathLength;
CHAR ImageName[256];
} SYSTEM_MODULE_INFORMATION_ENTRY, *PSYSTEM_MODULE_INFORMATION_ENTRY;
typedef struct {
ULONG Count;
SYSTEM_MODULE_INFORMATION_ENTRY Module[1];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;
typedef struct _SYSTEM_HANDLE
{
DWORD ProcessId;
// USHORT CreatorBackTraceIndex;
UCHAR ObjectTypeNumber;
UCHAR Flags;
USHORT Handle;
PVOID Object;
ACCESS_MASK GrantedAccess;
} SYSTEM_HANDLE, *PSYSTEM_HANDLE;
typedef struct _SYSTEM_HANDLE_INFORMATION
{
ULONG HandleCount; /* Or NumberOfHandles if you prefer. */
SYSTEM_HANDLE Handles[1];
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
typedef enum _SYSTEM_INFORMATION_CLASS {
SystemModuleInformation = 11,
SystemHandleInformation = 16
} SYSTEM_INFORMATION_CLASS;
typedef NTSTATUS(WINAPI *_NtQuerySystemInformation)(
SYSTEM_INFORMATION_CLASS SystemInformationClass,
PVOID SystemInformation,
ULONG SystemInformationLength,
PULONG ReturnLength
);
void main()
{
_NtQuerySystemInformation NtQuerySystemInformation=(_NtQuerySystemInformation)GetProcAddress(LoadLibrary(L"ntdll.dll"),"NtQuerySystemInformation");
PSYSTEM_MODULE_INFORMATION pmodinf;
PSYSTEM_HANDLE_INFORMATION phaninf;
ULONG len = 0;
char kname[260] = { 0 };
PVOID kbase = NULL;
DWORD cpid = GetCurrentProcessId();
HANDLE self = OpenProcess(PROCESS_QUERY_INFORMATION, NULL, cpid);
HANDLE self2 = NULL;
DuplicateHandle(GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(), &self2, NULL, NULL, NULL);
NtQuerySystemInformation(SystemModuleInformation, NULL, 0, &len);
pmodinf = (PSYSTEM_MODULE_INFORMATION)alloc(len);
RtlSecureZeroMemory(pmodinf, len);
NtQuerySystemInformation(SystemModuleInformation, pmodinf, len, &len);
lstrcpyA(kname, pmodinf->Module[0].ImageName);
kbase = pmodinf->Module[0].Base;
printf("kbase:%x\tkname:%s\n", kbase, kname);
HANDLE hntos = LoadLibraryA(kname);
len = 4096 * 16 * 16;
// NtQuerySystemInformation(SystemHandleInformation, NULL, 0, &len);
phaninf = (PSYSTEM_HANDLE_INFORMATION)alloc(len);
RtlSecureZeroMemory(phaninf, len);
NtQuerySystemInformation(SystemHandleInformation, phaninf, len, &len);
for (UINT i = 0; i < phaninf->HandleCount; i++)
{
if (phaninf->Handles[i].ProcessId==cpid)
{
printf("ObjectType:%d\n", phaninf->Handles[i].ObjectTypeNumber);
printf("Handle:%x,OpenProcessHandle:%x,DuplicateHandle:%x\n", phaninf->Handles[i].Handle, self,self2);
puts("");
if (phaninf->Handles[i].Handle==(USHORT)self)
{
puts("=============================");
printf("OpenProcessHandle\tEProcess Found!0x%x\n", phaninf->Handles[i].Object);
puts("=============================");
}
if (phaninf->Handles[i].Handle == (USHORT)self2)
{
puts("=============================");
printf("DuplicateHandle\tEProcess Found!0x%x\n", phaninf->Handles[i].Object);
puts("=============================");
}
}
}
freea(phaninf);
freea(pmodinf);
}
I want to get my process's EPROCESS address in winx64,but i failed. Do not use kernel function PsGetCurrrntProcess! I want my code works in user mode but kernel mode!

ffmpeg c++/cli wrapper for using in c# . AccessViolationException after call dll function by it's pointer

My target is to write a c++/cli wrap arount ffmpeg library, using by importing ffmpeg functions from dll-modules.
Later I will use this interface in c#.
This is my challenge, don't ask me why))
So i've implemented Wrap class, which is listed below:
namespace FFMpegWrapLib
{
public class Wrap
{
private:
public:
//wstring libavcodecDllName = "avcodec-56.dll";
//wstring libavformatDllName = "avformat-56.dll";
//wstring libswscaleDllName = "swscale-3.dll";
//wstring libavutilDllName = "avutil-54.dll";
HMODULE libavcodecDLL;
HMODULE libavformatDLL;
HMODULE libswsscaleDLL;
HMODULE libavutilDLL;
AVFormatContext **pFormatCtx = nullptr;
AVCodecContext *pCodecCtxOrig = nullptr;
AVCodecContext *pCodecCtx = nullptr;
AVCodec **pCodec = nullptr;
AVFrame **pFrame = nullptr;
AVFrame **pFrameRGB = nullptr;
AVPacket *packet = nullptr;
int *frameFinished;
int numBytes;
uint8_t *buffer = nullptr;
struct SwsContext *sws_ctx = nullptr;
void Init();
void AVRegisterAll();
void Release();
bool SaveFrame(const char *pFileName, AVFrame * frame, int w, int h);
bool GetStreamInfo();
int FindVideoStream();
bool OpenInput(const char* file);
AVCodec* FindDecoder();
AVCodecContext* AllocContext3();
bool CopyContext();
bool OpenCodec2();
AVFrame* AllocFrame();
int PictureGetSize();
void* Alloc(size_t size);
int PictureFill(AVPicture *, const uint8_t *, enum AVPixelFormat, int, int);
SwsContext* GetSwsContext(int, int, enum AVPixelFormat, int, int, enum AVPixelFormat, int, SwsFilter *, SwsFilter *, const double *);
int ReadFrame(AVFormatContext *s, AVPacket *pkt);
int DecodeVideo2(AVCodecContext *avctx, AVFrame *picture, int *got_picture_ptr, const AVPacket *avpkt);
int SwsScale(struct SwsContext *c, const uint8_t *const srcSlice[], const int srcStride[], int srcSliceY, int srcSliceH, uint8_t *const dst[], const int dstStride[]);
void PacketFree(AVPacket *pkt);
void BufferFree(void *ptr);
void FrameFree(AVFrame **frame);
int CodecClose(AVCodecContext *);
void CloseInput(AVFormatContext **);
bool SeekFrame(AVFormatContext *s, int stream_index, int64_t timestamp, int flags);
Wrap();
~Wrap();
bool GetVideoFrame(char* str_in_file, char* str_out_img, uint64_t time);
};
public ref class managedWrap
{
public:
managedWrap(){}
~managedWrap(){ delete unmanagedWrap; }
bool GetVideoFrameToFile(char* str_in_file, char* str_out_img, uint64_t time)
{
return unmanagedWrap->GetVideoFrame(str_in_file, str_out_img, time);
}
static Wrap* unmanagedWrap = new Wrap();
};
}
So the imports to libavcodec and etc. are succesful.
The problem is in AccessViolationException during calling dll func, for example, in OpenInput (i.e. av_open_input in native ffmpeg library)
The OpenInput func code is below:
bool FFMpegWrapLib::Wrap::OpenInput(const char* file)
{
typedef int avformat_open_input(AVFormatContext **, const char *, AVInputFormat *, AVDictionary **);
avformat_open_input* pavformat_open_input = (avformat_open_input *)GetProcAddress(libavformatDLL, "avformat_open_input");
if (pavformat_open_input == nullptr)
{
throw exception("Unable to find avformat_open_input function address in libavformat module");
return false;
}
//pin_ptr<AVFormatContext *> pinFormatContext = &(new interior_ptr<AVFormatContext *>(pCodecCtx));
pFormatCtx = new AVFormatContext*;
//*pFormatCtx = new AVFormatContext;
int ret = pavformat_open_input(pFormatCtx, file, NULL, NULL); // here it fails
return ret == 0;
}
So the problem, i think, is that class-fields of Wrap class are in secure memory. And ffmpeg works with native memory, initialising pFormatCtx variable by it's address.
Can I avoid this, or it is impossible?
Got the same problem, you need to initialise AVFormatContext object.
Good Example:
AVFormatContext *pFormatCtx = avformat_alloc_context();
Bad example:
AVFormatContext *pFormatCtx = NULL;

Swig unsigned char* to short[]

%apply (char* STRING,size_t LENGTH)
{
(char* dataBuffer, int size)
};
This is used for convert char* to byte[].
But I need to convert unsigned char* to short[]
%apply (unsigned char* STRING,size_t LENGTH)
{
(unsigned char* dataBuffer, int size)
};
This apply isn't working?
How can I fix it?

How to detect if SendMessage() API is called

I have the first program (written in Win32 API) using a lot of SendMessage() API; it's already done and works.
The problem is I want to write a second one that can detect SendMessage() is called in the first program and if possible, capture its data (HANDLE, WPARAM, LPARAM...)
Does anyone know solution for this problem?
The DLLStudy.dll:
EDIT: ok, this is what I have so far.
#include <windows.h>
#define SIZE 6
typedef int (WINAPI *pMessageBoxW)(HWND, LPCWSTR, LPCWSTR, UINT);
int WINAPI MyMessageBoxW(HWND, LPCWSTR, LPCWSTR, UINT);
void BeginRedirect(LPVOID);
pMessageBoxW pOrigMBAddress = NULL;
BYTE oldBytes[SIZE] = {0};
BYTE JMP[SIZE] = {0};
DWORD oldProtect, myProtect = PAGE_EXECUTE_READWRITE;
INT APIENTRY DllMain(HMODULE hDLL, DWORD Reason, LPVOID Reserved)
{
switch(Reason)
{
case DLL_PROCESS_ATTACH:
MessageBoxA(NULL, "Test", "OK", MB_OK);
pOrigMBAddress = (pMessageBoxW)
GetProcAddress(GetModuleHandle(L"user32.dll"), "MessageBoxW");
if(pOrigMBAddress != NULL)
BeginRedirect(MyMessageBoxW);
break;
case DLL_PROCESS_DETACH:
memcpy(pOrigMBAddress, oldBytes, SIZE);
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}
void BeginRedirect(LPVOID newFunction)
{
BYTE tempJMP[SIZE] = {0xE9, 0x90, 0x90, 0x90, 0x90, 0xC3};
memcpy(JMP, tempJMP, SIZE);
DWORD JMPSize = ((DWORD)newFunction - (DWORD)pOrigMBAddress - 5);
VirtualProtect((LPVOID)pOrigMBAddress, SIZE,
PAGE_EXECUTE_READWRITE, &oldProtect);
memcpy(oldBytes, pOrigMBAddress, SIZE);
memcpy(&JMP[1], &JMPSize, 4);
memcpy(pOrigMBAddress, JMP, SIZE);
VirtualProtect((LPVOID)pOrigMBAddress, SIZE, oldProtect, NULL);
}
int WINAPI MyMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uiType)
{
VirtualProtect((LPVOID)pOrigMBAddress, SIZE, myProtect, NULL);
memcpy(pOrigMBAddress, oldBytes, SIZE);
int retValue = MessageBoxW(hWnd, lpText, lpCaption, uiType);
memcpy(pOrigMBAddress, JMP, SIZE);
VirtualProtect((LPVOID)pOrigMBAddress, SIZE, oldProtect, NULL);
return retValue;
}
The Injector.cpp
#include <windows.h>
#include <iostream>
using namespace std;
char const Path[]="DLLStudy.dll";
int main(int argc, char* argv)
{
HANDLE hWnd, hProcess, AllocAdresse, hRemoteThread;
DWORD PID;
hWnd = FindWindow(0,"Notepad");
GetWindowThreadProcessId((HWND)hWnd, &PID);
hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, PID);
AllocAdresse = VirtualAllocEx(hProcess, 0, sizeof(Path), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hProcess, (void*)AllocAdresse, (void*)Path, sizeof(Path), 0);
hRemoteThread=CreateRemoteThread(hProcess, 0, 0, (LPTHREAD_START_ROUTINE) GetProcAddress(GetModuleHandle("kernel32.dll"),"LoadLibraryA"), AllocAdresse, 0, 0);
WaitForSingleObject(hRemoteThread, INFINITE);
VirtualFreeEx(hProcess, AllocAdresse, sizeof(Path), MEM_DECOMMIT);
CloseHandle(hProcess);
}
EDIT 2: Well, I've managed to make it work. So how to get data from SendMessage() if it is called?
You need to use CreateRemoteThread to inject a DLL into the first application. In the DLL's entrymain, you'd write code to remap the external call to SendMessage to your own SendMessageX which can then tell your other application when SendMessage is being called, and then pass the original call to the WIN32 subsystem.

Resources