C++/CLI stored procedure can't find resources - c++

I have some code which is fine in C++/CLI console application.
unsigned char* res2buffer()
{
HMODULE HInstance = 0x00;
try
{
HRSRC hrsrc = ::FindResourceW( HInstance, L"IDR_1251", RT_RCDATA);
if( hrsrc == NULL)
{
return nullptr;
}
const size_t nsize = ::SizeofResource( HInstance, hrsrc );
HGLOBAL hglob = ::LoadResource( HInstance, hrsrc );
LPVOID rdata = LockResource(hglob);
fuzzyRus = new unsigned char[ nsize ];
::memcpy( fuzzyRus, rdata, nsize );
UnlockResource(hglob);
::FreeResource(hglob);
return fuzzyRus;
}
catch(...)
{
}
return nullptr;
}
But is does not work in code made as Stored Procedure. Any clue? I guess I have to pass HInstance as a number is different then 0x00. The question is "Instance of what?"

You can get the HMODULE for your DLL like this:
HMODULE HInstance = NULL;
GetModuleHandleEx(
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
| GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
(LPCTSTR)res2buffer,
&HInstance
);

Make solution in managed way: File must be attached in linker option Input->Embeded Managed Resource File-> resource\rustbl.bin
static const unsigned char* GetRusTables() // get data from the resource file
{
Reflection::Assembly^ ca = Reflection::Assembly::GetExecutingAssembly();
IO::BinaryReader^ rusres = gcnew IO::BinaryReader( ca->GetManifestResourceStream( "rustbl.bin" ) );
array<unsigned char>^ buffPtr = rusres->ReadBytes( 413032 );
pin_ptr<unsigned char> fuzzyRus = &buffPtr[0];
return fuzzyRus;
}

Related

How to obtain both managed(dotnet) and native(C++) callstack of my project by dbghelp?

My project contains managed part(dotnet) and native(C++) part. I want to hook Winapi CreateFiles in my project by detours and log callstack. Now I have obtained a native callstack by invoking CaptureStackBackTrace and SymFromAddr api in dbghelp. But I meet some troubles when those functions are used in dotnet. as shown in the following picture, it can obtain correct callstack of native code(22, 21, 1, 0) but not work for managed code(20-2). may I have some methods to obtain both managed(dotnet) and un-managed(C++) callstack correctly? or maybe you have the best method to get callstack, could you help me?
dotnet produce:
public class CreateFileOrFolder
{
public void writeToFile(string pathString) {
System.IO.File.Create(pathString);
}
static void Main()
{
System.Console.WriteLine("Press any key to start.\n");
System.Console.ReadKey();
string fileName = "c.txt";
string pathString = System.IO.Path.Combine(#"D:\JunFiles\testDotNetProceduce", fileName);
// Verify the path that you have constructed.
Console.WriteLine("Path to my file: {0}\n", pathString);
CreateFileOrFolder creater = new CreateFileOrFolder();
if (!System.IO.File.Exists(pathString)) {
creater.writeToFile(pathString);
}
else
{
System.IO.File.Delete(pathString);
Console.WriteLine("File \"{0}\" already exists. but now it is deleted\n", fileName);
creater.writeToFile(pathString);
}
}
}
detours hook function:
HANDLE(*__stdcall oldCreateFile)(LPCWSTR,
DWORD,
DWORD,
LPSECURITY_ATTRIBUTES,
DWORD,
DWORD,
HANDLE) = CreateFileW;
HANDLE WINAPI newCreateFile(
_In_ LPCWSTR lpFileName,
_In_ DWORD dwDesiredAccess,
_In_ DWORD dwShareMode,
_In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
_In_ DWORD dwCreationDisposition,
_In_ DWORD dwFlagsAndAttributes,
_In_opt_ HANDLE hTemplateFile
) {
static BOOL state = FALSE;
printStack();
symbolSolve(process);
printf("HOOK sucess!\n");
std::cout << current_working_directory() << endl;
wchar_t newFileName[] = L".\\newFile.txt";
return oldCreateFile(
newFileName, // L".\\NewFile.txt", // Filename
//lpFileName,
dwDesiredAccess, // Desired access
dwShareMode, // Share mode
lpSecurityAttributes, // Security attributes
dwCreationDisposition, // Creates a new file, only if it doesn't already exist
dwFlagsAndAttributes, // Flags and attributes
NULL);
}
get callstack:
#define STACK_INFO_LEN 200
static HANDLE process;
unsigned int i;
void* stack[100];
unsigned short frames;
SYMBOL_INFO* symbol;
std::queue<std::pair<void*, unsigned short>> myQueue;
PDWORD hashValue = (PDWORD)malloc(sizeof(DWORD));
void printStack(void)
{
frames = CaptureStackBackTrace(0, 100, stack, hashValue);
void* stackTmp = stack;
}
DWORD WINAPI symbolSolve(LPVOID p) {
int myqueue_size = myQueue.size();
char* szBriefInfo = NULL;
static const int MAX_STACK_FRAMES = 12;
void* pStack[MAX_STACK_FRAMES];
static char szStackInfo[STACK_INFO_LEN * MAX_STACK_FRAMES];
static char szFrameInfo[STACK_INFO_LEN];
if (szBriefInfo == NULL) {
strcpy_s(szStackInfo, "stack traceback:\n");
}
else {
strcpy_s(szStackInfo, szBriefInfo);
}
symbol = (SYMBOL_INFO*)calloc(sizeof(SYMBOL_INFO) + 256 * sizeof(char), 1);
symbol->MaxNameLen = 255;
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
IMAGEHLP_LINE line;
line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
DWORD displacementLine = 0;
std::string strs = "";
strs += std::to_string(*hashValue);
for (i = 0; i < frames; i++) {
SymFromAddr(process, (DWORD64)(stack[i]), 0, symbol);
BOOL ret = SymGetLineFromAddr64(process, (DWORD64)(stack[i]), &displacementLine, &line);
_snprintf_s(szFrameInfo, sizeof(szFrameInfo), "%i: %s - 0x%0X ", frames - i - 1, symbol->Name, symbol->Address);
strcat_s(szStackInfo, szFrameInfo);
if (ret) {
_snprintf_s(szFrameInfo, sizeof(szFrameInfo), " | %s at %o \n", line.FileName, line.LineNumber);
strcat_s(szStackInfo, szFrameInfo);
}
else {
_snprintf_s(szFrameInfo, sizeof(szFrameInfo), "|error %d \n", GetLastError());
strcat_s(szStackInfo, szFrameInfo);
}
}
printf("%s \n", szStackInfo);
free(symbol);
return 0;
}
result:
The short answer is that dbhlp can't help with the managed parts of the stack walk.
It can be done, as windbg can do mixed mode stacks but it's specific to the version of .net and it also requires access to the full process memory to do it. I don't think the results from CaptureStackBackTrace will be enough, although since you are doing this in-process you may get away with it.
See the Mixed Mode Stackwalk article, which should give you pointers in the right direction.

Load .BIN file from resources inside exe

BIN file to resources of my executable file and then load it from resources instead of argv argument like : "loader.exe some.bin" i need a do this inside exe without putting file on disk here is code which i currently use:
LPSTR finalShellcode = NULL, data = NULL;
DWORD finalSize, dataSize;
DWORD dwOldProtect1 = 0;
SYSTEM_INFO sysInfo;
HMODULE test = LoadLibraryA("User32.dll");
if (argc < 2) {
return 0;
}
if (!GetFileContents(argv[1], &data, dataSize)) {
return 0;
}
if (data[0] == 'M' && data[1] == 'Z') {
if (!ConvertToShellcode(data, dataSize, HashFunctionName("SayHello"), "dave", 5, SRDI_CLEARHEADER, finalShellcode, finalSize)) {
return 0;
}
And here is GetFileContents function :
DWORD GetFileContents(LPCSTR filename, LPSTR *data, DWORD &size)
{
std::FILE *fp = std::fopen(filename, "rb");
if (fp)
{
fseek(fp, 0, SEEK_END);
size = ftell(fp);
fseek(fp, 0, SEEK_SET);
*data = (LPSTR)malloc(size + 1);
fread(*data, size, 1, fp);
fclose(fp);
return true;
}
return false;
}
Iam try make BIN file like RC data but without solution i dont know how i can embed .bin to resource then load it directly from resources any ideas any help? Thanks a lot
now i ADD test.bin as RCDATA with name IDR_RCDATA1 :
HMODULE hModule = GetModuleHandle(NULL);
HRSRC hResource = FindResource(hModule, MAKEINTRESOURCE(IDR_RCDATA1), RT_RCDATA); // substitute RESOURCE_ID and RESOURCE_TYPE.
HGLOBAL hMemory = LoadResource(hModule, hResource);
DWORD dwSize = SizeofResource(hModule, hResource);
LPVOID lpAddress = LockResource(hMemory);
char *bytes = new char[dwSize];
but i dont know ho to make it working...
A also read : How to load a custom binary resource in a VC++ static library as part of a dll? but without solution

LoadAccelerators for a specific resource language

I want to call LoadAccelerators but for a specific language in the resources. Is there a way to do it?
I did some reverse engineering and here's how to load it from memory for a specific LCID:
#pragma pack(push, 1) // exact fit - no padding
struct ACCEL_MEM{
BYTE fVirt;
BYTE byteReserved;
WORD wKey;
WORD wCmd;
WORD wReserved;
};
#pragma pack(pop)
HACCEL LoadAcceleratorsIndirectWithLCID(UINT nResourceID, LCID lcid)
{
//Open accelerators table with the 'nResourceID'
//'nResourceID' = Resource ID to use
//'lcid' = LCID to load resources for, or NULL to use the one from current thread
//RETURN:
// = HACCEL loaded -- must be removed with DestroyAcceleratorTable(), or
// = NULL if error
ASSERT(nResourceID);
HACCEL hAccel = NULL;
HINSTANCE hInst = ::GetModuleHandle(NULL);
if(hInst)
{
//Do we have a LCID?
if(lcid == NULL)
lcid = ::GetThreadLocale();
//Get language ID
LANGID langid = LANGIDFROMLCID(lcid);
//Try to load for specified resource
HRSRC hResource = ::FindResourceEx(hInst, RT_ACCELERATOR, MAKEINTRESOURCE(nResourceID), langid);
if(hResource == NULL)
{
//If failed, use default lcid
hResource = ::FindResource(hInst, MAKEINTRESOURCE(nResourceID), RT_ACCELERATOR);
}
if(hResource)
{
HGLOBAL hglb = LoadResource(hInst, hResource);
if(hglb)
{
LPVOID lpsz = LockResource(hglb);
DWORD dwcbSz = ::SizeofResource(hInst, hResource);
if(lpsz &&
dwcbSz)
{
ACCEL_MEM* pMem = (ACCEL_MEM*)lpsz;
//Count items in the table
int nCnt = 0;
ACCEL_MEM* pTest = pMem;
for(;; pTest++)
{
nCnt++;
if(pTest->fVirt & 0x80)
break;
}
//Reserve mem
ACCEL* pAccels = new ACCEL[nCnt];
//Parse data
for(int i = 0; i < nCnt; i++)
{
pAccels[i].fVirt = pMem[i].fVirt & 0x7f;
pAccels[i].key = pMem[i].wKey;
pAccels[i].cmd = pMem[i].wCmd;
}
//Create accel table
hAccel = ::CreateAcceleratorTable(pAccels, nCnt);
//Free mem
delete[] pAccels;
pAccels = NULL;
}
}
}
}
return hAccel;
}
You put your language-specific resources in a DLL. At run time, you load that DLL and specify the DLL's handle as the hInstance when you call LoadAccelerators.

AddFontMemResourceEx

The following code should work to load a font from a binary resource stored in my executable to system memory according to all of the examples I have found but it is not working. "myfont" is the name of the ttf associated with IDR_FONT in the resource file.
DWORD Count ;
HRSRC Resource = FindResource(GetModuleHandle(NULL),MAKEINTRESOURCE(IDR_FONT),"BINARY") ;
DWORD Length = SizeofResource(GetModuleHandle(NULL),Resource) ;
HGLOBAL Address = LoadResource(GetModuleHandle(NULL),Resource) ;
HANDLE Handle = AddFontMemResourceEx(Address,Length,0,&Count) ;
if(Handle==0)
{
MessageBox(hWnd,"Font load failed", "Error",NULL);
}
LOGFONT logfont; //set window font
logfont.lfCharSet = DEFAULT_CHARSET;
logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
logfont.lfEscapement = 0;
memcpy(logfont.lfFaceName, "myfont", LF_FACESIZE);
logfont.lfHeight = 14;
logfont.lfItalic = FALSE;
logfont.lfOrientation = 0;
logfont.lfOutPrecision = OUT_TT_PRECIS;
logfont.lfQuality = PROOF_QUALITY;
logfont.lfStrikeOut = FALSE;
logfont.lfUnderline = FALSE;
logfont.lfWeight = FW_DONTCARE;
hFont = CreateFontIndirect(&logfont);
Any ideas what I am doing incorrectly?
There are two problems with your code.
You are not checking any of the API functions for failure. Most likely, your call to FindResource() is failing because "BINARY" is not a standard resource type. User-defined resources should use RCDATA instead:
HRSRC Resource = FindResource(GetModuleHandle(NULL), MAKEINTRESOURCE(IDR_FONT), RT_RCDATA);
Or maybe FONT if it is an actual standard FONT resource:
HRSRC Resource = FindResource(GetModuleHandle(NULL), MAKEINTRESOURCE(IDR_FONT), RT_FONT);
The actual name of the resource type depends on the content of the .RC file you used to add the resource to the executable, though.
The other problem, and more importatly, is that you are not actually accessing the raw data of the resource so you can pass the real font data to AddFontMemResourceEx(). You need to use LockResource() for that.
Try something more like this instead:
HANDLE AddResourceFont(LPCTSTR ResID, DWORD *Installed)
{
if (Installed) *Installed = 0;
HMODULE hMod = GetModuleHandle(NULL);
DWORD Count, ErrorCode;
HRSRC Resource = FindResource(hMod, ResID, RT_RCDATA); // or RT_FONT or whatever your actual resource type is
if (!Resource)
{
ErrorCode = GetLastError();
//...
return NULL;
}
DWORD Length = SizeofResource(hMod, Resource);
if ((Length == 0) && (GetLastError() != 0))
{
ErrorCode = GetLastError();
//...
return NULL;
}
HGLOBAL Address = LoadResource(hMod, Resource);
if (!Address)
{
ErrorCode = GetLastError();
//...
return NULL;
}
PVOID FontData = LockResource(Address);
if (!FontData)
{
ErrorCode = GetLastError();
//...
return NULL;
}
HANDLE Handle = AddFontMemResourceEx(FontData, Length, 0, &Count);
if (!Handle)
{
ErrorCode = GetLastError();
//...
return NULL;
}
if (Installed) *Installed = Count;
return Handle;
}
.
DWORD Count = 0;
HANDLE hFont = AddResourceFont(MAKEINTRESOURCE(IDR_FONT), &Count);
if (hFont)
{
//...
RemoveFontMemResourceEx(hFont);
}

Retrieving DLL name, not calling application name

I've written two COM classes in C++, contained in a single MFC DLL. They're being loaded as plugins by a 3rd party application.
How can I get the file name, and version number, of the DLL from within those classes?
The main dll entry gives you the handle of your dll.
extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
and
GetModuleFileName(hInstance, buffer, MAX_PATH);
can be used to get the filename of the dll.
GetFileVersionInfoSize
GetFileVersionInfo
will be used to get the file version.
TCHAR fileName[MAX_PATH + 1];
GetModuleFileName(hInstance, fileName, MAX_PATH);
Where hInstance is the one you get in the DllMain function. Don't use GetModuleHandle(0), because that returns the HINSTANCE of the host application.
CString GetCallingFilename(bool includePath)
{
CString filename;
GetModuleFileName(AfxGetInstanceHandle(), filename.GetBuffer(MAX_PATH), MAX_PATH);
filename.ReleaseBuffer();
if( !includePath )
{
int filenameStart = filename.ReverseFind('\\') + 1;
if( filenameStart > 0 )
{
filename = filename.Mid(filenameStart);
}
}
return filename;
}
CString GetCallingVersionNumber(const CString& filename)
{
DWORD fileHandle, fileVersionInfoSize;
UINT bufferLength;
LPTSTR lpData;
VS_FIXEDFILEINFO *pFileInfo;
fileVersionInfoSize = GetFileVersionInfoSize(filename, &fileHandle);
if( !fileVersionInfoSize )
{
return "";
}
lpData = new TCHAR[fileVersionInfoSize];
if( !lpData )
{
return "";
}
if( !GetFileVersionInfo(filename, fileHandle, fileVersionInfoSize, lpData) )
{
delete [] lpData;
return "";
}
if( VerQueryValue(lpData, "\\", (LPVOID*)&pFileInfo, (PUINT)&bufferLength) )
{
WORD majorVersion = HIWORD(pFileInfo->dwFileVersionMS);
WORD minorVersion = LOWORD(pFileInfo->dwFileVersionMS);
WORD buildNumber = HIWORD(pFileInfo->dwFileVersionLS);
WORD revisionNumber = LOWORD(pFileInfo->dwFileVersionLS);
CString fileVersion;
fileVersion.Format("%d.%d.%d.%d", majorVersion, minorVersion, buildNumber, revisionNumber);
delete [] lpData;
return fileVersion;
}
delete [] lpData;
return "";
}