How to create DSN from custom ODBC Driver? - c++

For the last couple of weeks I'm struggling with ODBC in general. Made some progress but now I am stuck in setting up a dsn with custom ODBC driver.
What I understood, looking through postgres open source code.
I need to make a dll that contains two functions
1.ConfigDsn
2ConfigDriver
Here is example of my code
#include "pch.h"
#include <Windows.h>
BOOL WINAPI DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
BOOL ConfigDSN(
HWND hwndParent,
WORD fRequest,
LPCSTR lpszDriver,
LPCSTR lpszAttributes) {
MessageBox(NULL, L"TU", L"OVDJE", 0);
return TRUE;
}
BOOL ConfigDriver(
HWND hwndParent,
WORD fRequest,
LPCSTR lpszDriver,
LPCSTR lpszArgs,
LPSTR lpszMsg,
WORD cbMsgMax,
WORD* pcbMsgOut) {
MessageBox(NULL, L"TU", L"OVDJE", 0);
return TRUE;
}
When I try to Add a new DSN none of the message box shows.
If I add Message box call inside a DLLMain function, then the message box is displayed.
I'm assuming I missing a fundamental c++ knowledge in building dlls. Because I saw some .def files in resource folder inside postgres source code.
My question is how I need to make this dll so I could create a DSN with my own driver ?

Since you are building C++ code, all function names will be mangled. The ODBC functionslity probably expects to use the un-mangled names.
Use extern "C" to prevent name mangling:
extern "C" BOOL ConfigDSN(...) { ... }
extern "C" BOOL ConfigDriver(...) { ... }

Related

Can't find RequireSignedAppinit_DLLs in Registery

I am trying to do a small dll injection on my computer, and it doesn't seem to work.
I updated AppInit_DLLs with the path to my dll, and I read online that I need to set LoadAppinit_DLLs to 1 (which I have) and RequireSignedAppinit_DLLs to 0 for the injection to work.
but I can't find RequireSignedAppinit_DLLs in the registery..
My Registery
And here is my dll code: (It's very messy I am just trying to see if it will work before I actually make it clean)
#include "pch.h"
#define DLL_EXPORT
#include "mydll.h"
extern "C"
{
DECLDIR void Share()
{
MessageBox(NULL, (LPCWSTR)L"DLL injection!", (LPCWSTR)L"Hacked", 0);
}
void Keep()
{
MessageBox(NULL, (LPCWSTR)L"DLL injection!", (LPCWSTR)L"Hacked", 0);
}
DECLDIR void openWindow()
{
MessageBox(NULL, (LPCWSTR)L"DLL injection!", (LPCWSTR)L"Hacked", 0);
}
}
BOOL APIENTRY DllMain(HANDLE hModule, // Handle to DLL module
DWORD ul_reason_for_call,
LPVOID lpReserved) // Reserved
{
openWindow();
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
// A process is loading the DLL.
Keep();
Share();
openWindow();
break;
case DLL_THREAD_ATTACH:
// A process is creating a new thread.
Keep();
Share();
openWindow();
break;
case DLL_THREAD_DETACH:
// A thread exits normally.
Keep();
Share();
openWindow();
break;
case DLL_PROCESS_DETACH:
// A process unloads the DLL.
Keep();
Share();
openWindow();
break;
}
return TRUE;
}
Hope anyone can help...
Just create the RequireSignedAppinit_DLLs REG_WORD value yourself.
This is fine for experimentation but a real application should not modify these values because it decreases the security of the system.

Injected DLL Main loop crashes the process

I'm currently trying to inject a DLL into a project, but everytime i use a while loop the process crashes.
This is the code:
BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call,LPVOID lpReserved ){
switch(ul_reason_for_call){
case DLL_PROCESS_ATTACH:
while(char c = getch()){
if(c == 'p'){
MessageBox(0,L"CAPT",L"CAPT",MB_OK);
}
}
break;
}
return TRUE;
}
Since you changed your original question, I'll rearrange my answer a bit...
There are significant limits on what you can safely do in a DLL entry point.
Please read carefully through the remaks on the following page:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms682583(v=vs.85).aspx
and
https://msdn.microsoft.com/en-us/library/windows/desktop/aa370448(v=vs.85).aspx
For example, it shouldn't take more than 300ms (recommended time) during the DLL_PROCESS_ATTACH. You're also not returning anything (should be a boolean).
However, I think the main reason your software hangs is because MessageBox and/or getch() probably creates a deadlock there. Regarding the MessageBox use OutputDebugString instead, refer to this answer: https://stackoverflow.com/a/10981735/5874704
Also as suggested in comments:
Don't put the while loop in DllMain. Use CreateThread in DllMain to launch a new thread. Put the while loop there
Previously you also asked about the definition of the DLLMain. This is the "bare"-function of the DllMain:
BOOL WINAPI DllMain(
HINSTANCE hDllHandle,
DWORD nReason,
LPVOID Reserved)
{
BOOL bSuccess = TRUE;
switch ( nReason )
{
case DLL_PROCESS_ATTACH:
break;
case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
}
return bSuccess;
}

How to use the Detour library in C++ properly for a simple hook of a function with known memory adress?

I am having trouble to get my first hook using detour to work. I am using Detour 3.0.
My code compiles fine and I can inject the DLL using Winject , however, the function which I am suppose to hook doesnt seem to be hooked. I am trying to hook the function InsertDateTime in notepad.
http://www.9injector.com/winject-injector/
I have found the adress of the InsertDateTime in hex notation using IDA Pro Free.
Is there anything fundmatal misstakes in the code below or is the memory in the process not ceratinaly at the same time at every call?
My code for the injected DLL can be seen below:
// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
#include <windows.h>
#include "detours.h"
#pragma comment(lib, "detours.lib")
//
int(__stdcall* InsertDateTime)(int) = (int(__stdcall*)(int))(0x0100978A);
int MyInsertDateTime(int x) //Our function
{
//Messagebox
MessageBox(NULL, TEXT("InsertDateTime Just Got Called"), TEXT("InsertDateTime"), MB_OK);
return InsertDateTime(x); //Return the origional function
}
BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call) //Decide what to do
{
case DLL_PROCESS_ATTACH: //On dll attach
//InsertDateTime = (int (__stdcall*)(int))DetourAttach((PVOID*)0x0100978A, MyInsertDateTime);
//MessageBox(NULL, TEXT("InsertDateTime Just Got Called"), TEXT("InsertDateTime"), MB_OK);
DetourAttach((PVOID*)(&InsertDateTime), (PVOID)MyInsertDateTime);
//if(!errorCode) {
//Detour successful
break;
case DLL_THREAD_ATTACH: //On thread attach
DetourAttach((PVOID*)(&InsertDateTime), (PVOID)MyInsertDateTime);
break;
case DLL_THREAD_DETACH: //On thread detach
break;
case DLL_PROCESS_DETACH: //on process detach
DetourDetach((PVOID*)0x0100978A, InsertDateTime);
break;
}
return TRUE;
}
Also the code is mostly taken from an old tutorial using Detour 1.5.
Reference: http://www.moddb.com/groups/ibepex/tutorials/function-hooking
Detours is using a transaction system similar to databases. Before you can call Attach or Detach you have to start a transaction and the changes will only apply when you commit the transaction.
DetourTransactionBegin();
DetourAttach(...);
DetourAttach(...);
DetourTransactionCommit();
I think this was introduced in 2.0, which would explain why your tutorial code for 1.5 doesn't include it.

Pantheios logging in C++ DLL

Here is scenario:
I have testApp.cpp that has main function. And this testApp.cpp uses misc.dll and common.dll library.
I would like to create a log to file rather than to console.
So in testApp.cpp main() function, I use the following:
pantheios::pantheios_init();
pantheios_be_file_setFilePath("mylogfile.log");
pantheios::log_NOTICE(" START TESTAPP");
// Call function from misc.dll and common.dll
pantheios::log_NOTICE(" END TESTAPP ");
pantheios_be_file_setFilePath(NULL);
This WILL create mylogfile.log file with content 'START TESTAPP'
NOW THE PROBLEM:
I would also like to adding logging from misc.dll and common.dll to mylogfile.log.
In other words, if I add log in testMiscfunction() in misc.dll, I would like that log from
testMiscfunction() to be written to mylogfile.log.
And of course, same things with common.dll.
Now here is sample of DLL Entry for misc.dll
#include "pantheios/pantheios.hpp"
#include "pantheios/backends/bec.file.h"
#include "pantheios/implicit_link/core.h"
#include "pantheios/implicit_link/be.file.h"
extern "C" const char PANTHEIOS_FE_PROCESS_IDENTITY[] = "MISC_DLL";
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
pantheios::pantheios_init();
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
pantheios::pantheios_uninit();
break;
}
return TRUE;
}
So now in
testMiscFunction() { pantheios::log_NOTICE("I am testMiscFunction"); }
So "I am testMiscFunction" is not being written to mylogfile.txt Question is: Why? What need to be done.
Thanks....
The DLLs should link to Pantheios dynamically, so they'll use the same data. In this case you don't need to call Pantheios init/uninit functions from the DLL entry point (which is probably a bad idea anyway).

Detouring DrawText

I've downloaded and compiled the Microsoft detouring library. Inside my project I've included the header file and added the .lib file as a dependency. Everything compiles without errors. Now I've been trying to detour DrawText, but for some reason that detoured function doesn't get called at all. Similiarly I tried detouring the Sleep function and that worked as intended and the function I detoured to was called.
I'm not very well-versed in the business of API programming nor any other low level activities. I suspect it might have something to do with the fact that I'm trying to do this inside a console application instead of having the detouring done inside a DLL. I just find it strange that it would be able to detour Sleep in that case.
Is there something wrong with my approach or does the fault lie in the code?
#include <windows.h>
#include <stdio.h>
#include "detours.h"
int ( WINAPI *Real_DrawText )(HDC a0, LPCSTR a1, int a2, LPRECT a3, UINT a4) = DrawTextA;
int Mine_DrawText(HDC hdc, LPCSTR text, int nCount, LPRECT lpRect, UINT uOptions)
{
printf("TEST");
return Real_DrawText(hdc, text, nCount, lpRect, uOptions);
}
int main(int argc, char **argv)
{
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)Real_DrawText, Mine_DrawText);
DetourTransactionCommit();
printf("Calling Sleep\n");
Sleep(1000);
printf("Second callout");
Sleep(5000);
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(PVOID&)Real_DrawText, Mine_DrawText);
DetourTransactionCommit();
return 0;
}
Based on your code-example, it seems you're only detouring your own process. Therefore detouring DrawText doesn't output anything. Perhaps, you need to inject your code to desired target's process memory and detour the API call from there. For example, you can create system wide CBT hook which works kind of a.. launch point to your detouring needs. Something like this, to point you out a direction:
LRESULT CALLBACK CBTProcedure(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode < 0)
return CallNextHookEx(g_hHook, nCode, wParam, lParam);
else if (!g_pClient)
return 0;
HWND hWnd = (HWND)wParam;
if (!hWnd)
return 0;
switch (nCode) {
case HCBT_ACTIVATE:
/** Here, you can check up against the handle to see,
* if the target window is the one you're looking for...
*
*/
if (!g_pClient->IsRegisteredWindow(hWnd))
if (g_pClient->RegisterWindow(hWnd)) {
}
break;
case HCBT_DESTROYWND:
if (g_pClient->IsRegisteredWindow(hWnd))
g_pClient->UnregisterWindow(hWnd);
break;
}
return 0;
}
bool __0XYOUROWN_API InstallHook()
{
// Call this one from your main process; set's up the system-wide hook.
g_hHook = SetWindowsHookEx(WH_CBT, (HOOKPROC)CBTProcedure, g_hInstance, 0);
/** #pragma data_seg("Shared")
* HHOOK g_hHook = NULL;
* #pragma data_seg()
*/
return g_hHook != NULL;
}
/** The actual DLL...
*
*
*/
BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
g_hInstance = (HINSTANCE)hModule;
if (::GetModuleHandle(_T("THEDESIREDMODULE.EXE")) != NULL) {
g_pClient = new Client();
if (g_pClient) {
InitializeCriticalSection(&g_CriticalSection); // You can setup a critic. sec. for later synchronization...
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)Real_DrawTextW, Mine_DrawTextW);
DetourTransactionCommit();
}
}
break;
case DLL_THREAD_ATTACH: break;
case DLL_THREAD_DETACH: break;
case DLL_PROCESS_DETACH:
if (::GetModuleHandle(_T("THEDESIREDMODULE.EXE")) != NULL) {
if (g_pClient) {
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(PVOID&)Real_DrawTextW, Mine_DrawTextW);
DetourTransactionCommit();
delete g_pClient;
g_pClient = NULL;
}
}
break;
}
}
It seems you're assuming printf() will call DrawText(). It won't. DrawText() is a GDI function. printf() goes to WriteConsole(). These don't intermix. "Console Windows" are quite unlike all other windows. This distinction is a fundamental architectural one; they're even managed by separate kernel components.
Only a side note: EasyHook - The reinvention of Windows API Hooking is an open source (LGPL) project developing a successor to Detours. It is quite mature already.