Calling dll from a Win32 Console Application [C] - c

Hi everyone and thank you for your time. This was created in Visual Studio 2012,and I'm using the standard Windows Libraries.
I am attempting to call a DLL function explicitly and I believe the code I've written is correct; however, I am receiving an error. I'm not sure if it's an error in something that I've written in the small C console application or from the DLL which I do not have access to the internal workings of.
//global area
HINSTANCE _createInstance;
typedef UINT (CALLBACK* LPFNDLLFUNCLOOKUP)(AccuInput*, AccuOut*);
LPFNDLLFUNCLOOKUP lpfnDllFuncCASSLookup;
typedef UINT (CALLBACK* LPFNDLLFUNCINIT)(BSTR);
LPFNDLLFUNCINIT lpfnDllFuncInit;
typedef UINT (CALLBACK* LPFNDLLFUNCCLOSE)();
LPFNDLLFUNCCLOSE lpfnDllFuncClose;
HMODULE unmanagedLib;
Here is my main function:
int main() {
// Load Library
BSTR configFile;
unmanagedLib = LoadLibraryA((LPCSTR) "AccuAddressUnMgd.dll");
// Initialize AccuAddress COM dll
lpfnDllFuncInit = (LPFNDLLFUNCINIT)GetProcAddress(unmanagedLib, (LPCSTR)"Init");
// This function will lookup the address
lpfnDllFuncCASSLookup = (LPFNDLLFUNCLOOKUP)GetProcAddress(unmanagedLib, (LPCSTR)"AccuCassLookup");
// This function will call AccuAddress COM DLL Close function
lpfnDllFuncClose = (LPFNDLLFUNCCLOSE)GetProcAddress(unmanagedLib, (LPCSTR)"Close");
// Append “config.acu” file path.
configFile = SysAllocString(L"C:\PathTo\Config.acu");
printf("ConfigPath created");
lpfnDllFuncInit(configFile);
printf("ConfigFile consumed");
SysFreeString(configFile);
return 0;
}
This is the error that I receive:
Unhandled exception at at 0x75D4C54F in RDISample1.exe: Microsoft C++ exception: _com_error at memory location 0x001AFAC0.
The error occurs at:
lpfnDllFuncInit(configFile);
So, I guess my question is two parts. Based off the code can I say for a fact that the error is in the DLL function?
Second question, when calling GetProcAddress what would be the point (if any) for encapsulating the string in LPCSTR like a function versus typecasting?
ie
lpfnDllFuncClose = (LPFNDLLFUNCCLOSE)GetProcAddress(unmanagedLib, LPCSTR("Close"));
Thanks again for the help. I've been doing a fair amount of research yet DLLs still have been puzzled.

The initial error is caused by the library you're using failing to correctly handle a file that doesn't exist.
The path you gave contains single slashes \, which are treated as escape characters, not path separators. Path separators must be escaped, i.e. \\ to be treated correctly.

There is no point casting a string literal to LPCSTR.
As for the _com_error that is definitely coming from the DLL. I would suggest wrapping that in a:
try
{
...
} catch(_com_error const & e)
{
wprintf(L"Caught a com error: %s\r\n", e.ErrorMessage());
}
And then you might be able to figure out what is wrong.

Related

Calling a DLL function with an allocated character buffer that the function fills in Inno Setup

I am using (Unicode) Inno Setup 6.0.5 on Windows 10 64-bit.
The exported symbol, I want to use has the signature:
typedef int(__stdcall *GetDirVST2x86) (LPWSTR lpString1);
The Inno Setup [Code] section has its declaration as:
function GetDirVST2x86(var lpString1: String): Integer;
external 'GetDirVST2x86#files:R2RINNO.DLL stdcall setuponly';
where, lpString1 will contain a pointer to the wide-string after the function returns and R2RINNO.DLL is a 32-bit DLL.
Now my problem is, if I compile and run this setup, a read access violation occurs right when I try to retrieve the value. I get the correct result when I execute this same function from a C program. Removing the var from the prototype declaration in Inno script fetches an empty (or possibly) empty or blank string, so that doesn't help either.
I don't have the source for the DLL I wish to use, and I figured out the signature from IDA. The scripting engine Inno Setup seems hopelessly inadequate as it doesn't support pointers at all.
One interesting thing I observed was if I changed the type of lpString1 to Cardinal or Integer and used IntToStr to fetch the string I got the value of the directory in which the setup was getting created.
Here's a working C code:
#include <windows.h>
#include <stdio.h>
#define _UNICODE
#define UNICODE
typedef int(WINAPI *GetDirVST2x86) (LPWSTR );
int main() {
HMODULE hModule = LoadLibrary("R2RINNO.DLL");
if (NULL != hModule) {
GetDirVST2x86 pGetDirVST2x86 = (GetDirVST2x86) GetProcAddress (hModule, "GetDirVST2x86");
if (NULL != pGetDirVST2x86) {
LPWSTR lpszVST2x86;
pGetDirVST2x86(lpszVST2x86);
wprintf(lpszVST2x86);
}
FreeLibrary(hModule);
}
}
Here's the output:
C:\Program Files (x86)\Steinberg\VstPlugins
Here's the IDA screenshot of the function I want to use:
Pascal Script equivalent of the C declaration should be:
function GetDirVST2x86(lpString1: string): Integer;
external 'GetDirVST2x86#files:R2RINNO.DLL stdcall setuponly';
(i.e. no var, as it is an input character pointer argument).
Assuming the function contract is that you (as a caller) allocate a buffer and provide it to the function to be filled in, you should call the function like this:
var
Buf: string;
begin
{ Allocate buffer for the result large enough according to the API specification }
SetLength(Buf, 1000);
GetDirVST2x86(Buf);
SetLength(Result, Pos(#0, Result) - 1);
end;
See also How to return a string from a DLL to Inno Setup?

Why is Ghidra appending a memory address to a string that is displayed instead of a variable?

This is my first time using Ghidra and debugging. My project deals with reverse engineering a Dos executable from 2007, to understand how it generates a code.
I looked for the strings I can read when launching the program through wine (debugging under linux) and found one place :
/* Reverses the string */
__strrev(local_8);
local_4 = 0;
DISPLAY_MESSAGE(s__Code_=_%s_0040704c);
with DISPLAY_MESSAGE being :
int __cdecl DISPLAY_MESSAGE(byte *param_1)
{
int iVar1;
int errorCode;
iVar1 = FUN_004019c0((undefined4 *)&DAT_004072e8);
errorCode = FUN_00401ac0((char **)&DAT_004072e8,param_1,(undefined4 *)&stack0x00000008);
FUN_00401a60(iVar1,(int *)&DAT_004072e8);
return errorCode;
}
I named the function "DISPLAY_MESSAGE" because I saw the string on the screen ;-). I would like to name it printf but its signature does not match the one of printf since it takes byte * instead of char *, ... as input parameters and returns an int instead of void for the actual printf.
The string "Code = %s" (stripping the CRs and new lines) is actually located at address "0040704c", and I am very surprised not to see the variable holding the generated code value instead (that could help me rename the variables).
If I change the signature to the one of printf it yields :
DISPLAY_MESSAGE(s__Code_=_%s_0040704c,local_8)
which looks better, because local_8 could be the code, but I don't know if it is correct to change the signature like this (since then the local variable that I renamed errorCode is never used whereas it was returned before signature change).
void __cdecl DISPLAY_MESSAGE(char *param_1,...)
{
int iVar1;
int errorCode;
iVar1 = FUN_004019c0((undefined4 *)&DAT_004072e8);
FUN_00401ac0((char **)&DAT_004072e8,(byte *)param_1,(undefined4 *)&stack0x00000008);
FUN_00401a60(iVar1,(int *)&DAT_004072e8);
return;
}
So my questions are :
Why is Ghidra appending _0040704c to the string (should it help me, and how should I make use of this piece of info) ?
If my signature change is correct, what prevents Ghidra from finding the correct signature from its analysis ?
Should I think there is a problem with the function signature whenever I see undefinedX as it appears in DISPLAY_MESSAGE ?
Any help greatly appreciated!

Struggling with conversion of an LPBYTE to char* or anything alike in C (Chinese output?)

I've got a C project that I'm working on and I'm having a problem.
The program reads a string that is echoed by a .php page. It uses this code
to read the data and appoint it to a variable, which get sent to the Commands() function:
LPSTR szBuffer=(LPSTR)chunk+0x1000;
DWORD dwRead;
if (CWA(_HttpSendRequestA, wininet, hHttpRequest, szHeaders, lpstrlenA(szHeaders), szReq, lpstrlenA(szReq)) != 0)
{
CWA(_InternetReadFileA, wininet, hHttpRequest, szBuffer, 0x400, &dwRead);
if (dwRead)
Commands((LPBYTE)szBuffer, dwRead);
}
As you can see the data is sent to the Commands() function, which receives the LPBYTE szBuffer (named "command" in the function) and the DWORD dwRead (named "size" in the function).
In the Commands() function, it's supposed to read the string that it read from the .php page. However, since the data seems to be stored as LPBYTE, I've done a lot of things trying to get that to a char*. When I thought I had finally got it however, I tried outputting it using a MessageBox (to see if it displays the string it should have read). However, this returns me Chinese characters (while the original string should be this:
"TASKci=0C73CCFD206BBD011E7087CE0806E6F6E69630,job=dlex,ti=AD62A5950B76F3812C542C24040EACE9,pr=https,ur=//test.com/test.txt,cl=".
Screenshot of what it returns me: http://prntscr.com/h0p5iw
How the code inside Commands() looks:
BOOL Commands(LPBYTE command, DWORD size) {
LPTSTR x = (LPTSTR)((char*)command);
{
int msgboxID = MessageBox(
NULL,
x,
(LPCWSTR)L"Woop",
MB_ICONWARNING | MB_CANCELTRYCONTINUE | MB_DEFBUTTON2 );
}
CWA(Sleep, kernel32, 100);
return 1; }
I'm new at C (I've only written stuff in C# before) so I am sorry if I am asking any dumb questions, I've really tried my best but I cannot seem to find any solution by myself.
Also, keep in mind that everything except for the stuff inside the Commands() function is not coded by me but by someone who is way more experienced. That code should be fine and I am sure that it is reading the data from the page, it's probably just me screwing up a conversion somewhere.
A narrow string (char*) tends to look like Chinese when you use it somewhere that expects a wide UTF-16 Unicode string.
You cannot just cast the string to change its type, you need to call MultiByteToWideChar.

Use a dynamic library dll in C program

I want to use a dll-file in my C-Code, but are very confused about the syntax.
My Story: I made a simple function in Matlab ( f(x1,x2)=x1*x2 ), with the "Matlab Coder" I translated it to C-Code and generated an exe, I could run it from the terminal with arguments.Now I generated a dll instead of an exe and want to use the dll.
Since now I could not make Code explanations, I googled, make work for me. I look up Syntax in http://en.cppreference.com/w/ but for my surprise there wasn't even an entry for e.g. GetProcAddress or LoadLirbary.
Here is the C-Code in which I would like to use the dll:
#include <stdio.h>
#include <stdlib.h>
/*
* In my dream I would load the dll function here
* with something like Load(mytimes4.dll)
*/
int main(int argc, char *argv[]) {
double x1,x2,myresult;
//Load Arguments from Terminal
sscanf(argv[1], "%lf", &x1);
sscanf(argv[2], "%lf", &x2);
// Use and print the function from mytimes4.dll
myresult = mytimes4(x1,x2);
printf("%3.2f\n",myresult);
return 0;
}
After generating the dll, Matlab gave me the following folder:
"dll-folder" produced by Matlab
Can someone give me a most simple but complete Code that would work with my example? What files are needed (maybe .def or .exp)? Also for Explanations of the lines involved using the dll I would be gratefull. Or if not, you maybe have some background knowledge that makes the complex syntax reasonable.Thanks in advance!
System information: Windows 7 Pro 64, Matlab 64 2016b, gcc cygwin 64, eclipse ide.
With the link of thurizas I could solve my problem.
https://msdn.microsoft.com/en-us/library/windows/desktop/ms686944(v=vs.85).aspx
I copied the code from the side. Below you can see the code with additional comments of mine and with ,in my opinion, more clearly naming. Thus it is probably easier to use for beginners as I am.
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
/*Declaration of the function,contained in dll, as pointer with the arbitrary pointer name
"*MYFUNCTIONPOINTER" (not sure if it has to be in big letters).
In my case the function means simply f(x1,x2) = x1*x2 and is thus as double declared*/
typedef double (*MYFUNCTIONPOINTER)(double, double);
int main() {
HINSTANCE hinstLib;
//"myfunction" is the arbitrary name the function will be called later
MYFUNCTIONPOINTER myfunction;
BOOL fFreeResult, fRunTimeLinkSuccess = FALSE;
//Tell the dll file
hinstLib = LoadLibrary(TEXT("mypersonal.dll"));
if (hinstLib != NULL)
{
/* At this line "myfunction" gets its definition from "MYFUNCTIONPOINTER"
and can be used as any other function.The relevant function in the dll has
to be told here.*/
myfunction = (MYFUNCTIONPOINTER) GetProcAddress(hinstLib, "mydllfunction");
// If the function address is valid, call the function.
if (NULL != myfunction)
{
fRunTimeLinkSuccess = TRUE;
// The function can be used.
double myoutput;
myoutput = myfunction(5,7);
printf("%f\n",myoutput);
getchar();
}
// Free the DLL module.
fFreeResult = FreeLibrary(hinstLib);
}
// If unable to call the DLL function, use an alternative.
if (! fRunTimeLinkSuccess)
printf("Message printed from executable\n");
return 0;
}

How to use winapi functions in ring0 (kernel mode)?

I can't call FileTimeToSystemTime() method in driver. The error is:
error C4013: 'FileTimeToSystemTime' undefined; assuming extern returning int.
Also I can not include windows.h because I already included ntddk.h, and it will cause a lot of errors.
If I declare it as BOOL FileTimeToSystemTime(IN const PFILETIME, OUT PSYSTEMTIME); in the header I get next errors:
error C2061: syntax error : identifier 'FileTimeToSystemTime'
error C2059: syntax error : ';'
error C2059: syntax error : 'type'
error C4013: 'FileTimeToSystemTime' undefined; assuming extern returning int
And finally, If I write an implementation for this method:
BOOL FileTimeToSystemTime(const PFILETIME pFileTime, PSYSTEMTIME pSystemTime)
{
CALL_ENTRY
long long tmp;
memcpy(&tmp, pFileTime, sizeof (FILETIME));
time_t aTime_t = tmp / 10000;
tm aTm;
if (!gmtime_r(&aTime_t, &aTm ))
return FALSE;
pSystemTime->wYear = aTm.tm_year + 1900;
pSystemTime->wMonth = aTm.tm_mon;
pSystemTime->wDayOfWeek = aTm.tm_wday;
pSystemTime->wDay = aTm.tm_mday;
pSystemTime->wHour = aTm.tm_hour;
pSystemTime->wMinute = aTm.tm_min;
pSystemTime->wSecond = aTm.tm_sec;
pSystemTime->wMilliseconds = 0;
return TRUE;
}
I got the same errors as listed above. What is the right way to call this method in kernel mode ? Or how to call winapi functions from windows driver in general ?
The winapi is a sub-system on top of the native operating system. There were original three sub-systems for Windows NT: Posix, OS/2 and Win32. Designed to make porting programs from other operating system easy. Win32 was heavily influenced by the api for Windows 3.x. Posix and OS/2 were largely ignored and have been removed, Win32 won by a land-slide. These days called "Winapi" to avoid the "32", it was ported to 64-bit code with very modest changes.
In device driver land, you no longer work with such a sub-system, you program the native operating system. So you'll need to forget the winapi functions and use the native API instead.
You obtain the system time with KeQuerySystemTime(). Convert to local time if necessary ExSystemTimeToLocalTime(). You can generate the equivalent of SYSTEMTIME with the RtlTimeToTimeFields() helper function.

Resources