Jump to content
Tuts 4 You

Import apis from cutom dll via LoadLib & GetprocAddess


deepzero

Recommended Posts

Posted

Hi,

i am trying to use bassmod.dll to play tracker music in C++.

This is a start (with a little help from msdn :) ):

typedef BOOL (WINAPI *wapi)(DWORD, DWORD, DWORD);
int main()
{
HMODULE basshndl = LoadLibraryA("C:\\x.dll");
cout << "Handel: " << basshndl<< "\n";
bassinit = GetProcAddress(basshndl, "BASSMOD_Init");
cout << "bassmod_init: " << binit << "\n"; bassinit(-1,44100,0);}

the initialization went fine -> works.

However, every api has a different returnvalue/arguments, so i`d need a different typedef for every api...which is unpractical.

i found this on the web:

.....
GCNA fGetComputerName;
BOOL nokernel32 = FALSE;
DWORD nokernel32err = 0;
BOOL nouser32 = FALSE;
DWORD nouser32err = 0;
BOOL noadvapi32 = FALSE;
BOOL noadvapi32lsa = FALSE;
DWORD noadvapi32err = 0;
BOOL nogdi32 = FALSE;
DWORD nogdi32err = 0;
BOOL nows2_32 = FALSE;
DWORD nows2_32err = 0;
BOOL nowininet = FALSE;
DWORD nowinineterr = 0;
BOOL noicmp = FALSE;
DWORD noicmperr = 0;
BOOL nonetapi32 = FALSE;
DWORD nonetapi32err = 0;
BOOL nodnsapi = FALSE;
DWORD nodnsapierr = 0;
BOOL noiphlpapi = FALSE;
BOOL noiphlpapinsp = FALSE;
DWORD noiphlpapierr = 0;
BOOL nompr = FALSE;
DWORD nomprerr = 0;
BOOL noshell32 = FALSE;
DWORD noshell32err = 0;
BOOL noodbc32 = FALSE;
DWORD noodbc32err = 0;
BOOL noavicap32 = FALSE;
DWORD noavicap32err = 0;
BOOL nopsapi = FALSE;
DWORD nopsapierr = 0;
BOOL nopstore = FALSE;
DWORD nopstoreerr = 0;
BOOL noshlwapi = FALSE;
DWORD noshlwapierr = 0;
......
BOOL LoadDLLs(void)
{
.....
HMODULE kernel32_dll = GetModuleHandle("kernel32.dll"); HMODULE user32_dll = LoadLibrary("user32.dll"); HMODULE advapi32_dll = LoadLibrary("advapi32.dll");
fRegEnumKeyEx = (REKE)GetProcAddress(advapi32_dll,"RegEnumKeyExA"); fOpenSCManager = (OSCM)GetProcAddress(advapi32_dll,"OpenSCManagerA");
fOpenService = (OS)GetProcAddress(advapi32_dll,"OpenServiceA");
fStartService = (SS)GetProcAddress(advapi32_dll,"StartServiceA");
fControlService = (CS)GetProcAddress(advapi32_dll,"ControlService");
fDeleteService = (DS)GetProcAddress(advapi32_dll,"DeleteService");
fCloseServiceHandle = (CSH)GetProcAddress(advapi32_dll,"CloseServiceHandle");
fEnumServicesStatus = (ESS)GetProcAddress(advapi32_dll,"EnumServicesStatusA");
fIsValidSecurityDescriptor = (IVSD)GetProcAddress(advapi32_dll,"IsValidSecurityDescriptor");
fCreateService = (CRS)GetProcAddress(advapi32_dll,"CreateServiceA");
fStartServiceCtrlDispatcher = (SSCD)GetProcAddress(advapi32_dll,"StartServiceCtrlDispatcherA");
fImpersonateLoggedOnUser = (ILOU)GetProcAddress(advapi32_dll,"ImpersonateLoggedOnUser");
fLockServiceDatabase = (LSD)GetProcAddress(advapi32_dll,"LockServiceDatabase");
fQueryServiceLockStatus = (QSLS)GetProcAddress(advapi32_dll,"QueryServiceLockStatusA");
fChangeServiceConfig2 = (CSC2)GetProcAddress(advapi32_dll,"ChangeServiceConfig2A");
fUnlockServiceDatabase = (USD)GetProcAddress(advapi32_dll,"UnlockServiceDatabase");
fRegisterServiceCtrlHandler = (RSCH)GetProcAddress(advapi32_dll,"RegisterServiceCtrlHandlerA");.....}

So though of something like this:

int main()
{
HMODULE basshndl = LoadLibraryA("C:\\x.dll");
cout << "Handel: " << basshndl<< "\n"; BSINI bassinit0;
bassinit0 = (BSINI)GetProcAddress(basshndl, "BASSMOD_Init");
//cout << "bassmod_init: " << binit << "\n"; bassinit0(-1,44100,0);}

which doesnt work... :(

So, the question is: how can i make lots of apis imported via LoadLibrary & GetpRocAddress easy available in my code?

dp0 :)

Posted (edited)

Here is a modified version of bass.h which allows either implicit or explicit linking to bass.dll. All i did was added a define and an #ifdef to differentiate between the two. Then i copied all the function definitions across, changing them to function ptr prototypes:


#ifdef BASS_EXPLICIT_LINKING
//Explicit linking function pointer prototypes here
typedef BOOL (WINAPI *BASS_SetConfigFn)(DWORD option, DWORD value);
typedef DWORD (WINAPI *BASS_GetConfigFn)(DWORD option);
typedef BOOL (WINAPI *BASS_SetConfigPtrFn)(DWORD option, void *value);
typedef void *(WINAPI *BASS_GetConfigPtrFn)(DWORD option);
typedef DWORD (WINAPI *BASS_GetVersionFn)();
typedef int (WINAPI *BASS_ErrorGetCodeFn)();
typedef BOOL (WINAPI *BASS_GetDeviceInfoFn)(DWORD device, BASS_DEVICEINFO *info);
#if defined(_WIN32) && !defined(_WIN32_WCE)
typedef BOOL (WINAPI *BASS_InitFn)(int device, DWORD freq, DWORD flags, HWND win, const GUID *dsguid);
#else
typedef BOOL (WINAPI *BASS_InitFn)(int device, DWORD freq, DWORD flags, void *win, void *dsguid);
#endif

I've compiled the basstest project from the download package using this method, if you want to look at it. Where there was a call to a bass.dll function, i declared an instance of the required function and because this is a C project i created a function which initializes all required bass.dll functions. It disassembles to this in Olly:

(I've placed it in a spoiler box because its large[ish] and i didn't want to make the post too big)


00401000 /$ 55 PUSH EBP
00401001 |. 8BEC MOV EBP,ESP
00401003 |. 68 00004100 PUSH 00410000 ; /FileName = "bass.dll"
00401008 |. FF15 08E04000 CALL DWORD PTR [<&KERNEL32.LoadLibraryA>] ; \LoadLibraryA
0040100E |. A3 90204100 MOV DWORD PTR [412090],EAX
00401013 |. 833D 90204100 00 CMP DWORD PTR [412090],0
0040101A |. 75 07 JNZ SHORT 00401023
0040101C |. 33C0 XOR EAX,EAX
0040101E |. E9 E1010000 JMP 00401204
00401023 |> 68 0C004100 PUSH 0041000C ; /ProcNameOrOrdinal = "BASS_StreamCreateFile"
00401028 |. A1 90204100 MOV EAX,DWORD PTR [412090] ; |
0040102D |. 50 PUSH EAX ; |hModule => NULL
0040102E |. FF15 1CE04000 CALL DWORD PTR [<&KERNEL32.GetProcAddress>] ; \GetProcAddress
00401034 |. A3 7C204100 MOV DWORD PTR [41207C],EAX
00401039 |. 68 24004100 PUSH 00410024 ; /ProcNameOrOrdinal = "BASS_StreamFree"
0040103E |. 8B0D 90204100 MOV ECX,DWORD PTR [412090] ; |
00401044 |. 51 PUSH ECX ; |hModule => NULL
00401045 |. FF15 1CE04000 CALL DWORD PTR [<&KERNEL32.GetProcAddress>] ; \GetProcAddress
0040104B |. A3 74204100 MOV DWORD PTR [412074],EAX
00401050 |. 68 34004100 PUSH 00410034 ; /ProcNameOrOrdinal = "BASS_ChannelPlay"
00401055 |. 8B15 90204100 MOV EDX,DWORD PTR [412090] ; |
0040105B |. 52 PUSH EDX ; |hModule => NULL
0040105C |. FF15 1CE04000 CALL DWORD PTR [<&KERNEL32.GetProcAddress>] ; \GetProcAddress
00401062 |. A3 48204100 MOV DWORD PTR [412048],EAX
00401067 |. 68 48004100 PUSH 00410048 ; /ProcNameOrOrdinal = "BASS_ChannelStop"
0040106C |. A1 90204100 MOV EAX,DWORD PTR [412090] ; |
00401071 |. 50 PUSH EAX ; |hModule => NULL
00401072 |. FF15 1CE04000 CALL DWORD PTR [<&KERNEL32.GetProcAddress>] ; \GetProcAddress
00401078 |. A3 64204100 MOV DWORD PTR [412064],EAX
0040107D |. 68 5C004100 PUSH 0041005C ; /ProcNameOrOrdinal = "BASS_MusicLoad"
00401082 |. 8B0D 90204100 MOV ECX,DWORD PTR [412090] ; |
00401088 |. 51 PUSH ECX ; |hModule => NULL
00401089 |. FF15 1CE04000 CALL DWORD PTR [<&KERNEL32.GetProcAddress>] ; \GetProcAddress
0040108F |. A3 60204100 MOV DWORD PTR [412060],EAX
00401094 |. 68 6C004100 PUSH 0041006C ; /ProcNameOrOrdinal = "BASS_MusicFree"
00401099 |. 8B15 90204100 MOV EDX,DWORD PTR [412090] ; |
0040109F |. 52 PUSH EDX ; |hModule => NULL
004010A0 |. FF15 1CE04000 CALL DWORD PTR [<&KERNEL32.GetProcAddress>] ; \GetProcAddress
004010A6 |. A3 84204100 MOV DWORD PTR [412084],EAX
004010AB |. 68 7C004100 PUSH 0041007C ; /ProcNameOrOrdinal = "BASS_SampleLoad"
004010B0 |. A1 90204100 MOV EAX,DWORD PTR [412090] ; |
004010B5 |. 50 PUSH EAX ; |hModule => NULL
004010B6 |. FF15 1CE04000 CALL DWORD PTR [<&KERNEL32.GetProcAddress>] ; \GetProcAddress
004010BC |. A3 88204100 MOV DWORD PTR [412088],EAX
004010C1 |. 68 8C004100 PUSH 0041008C ; /ProcNameOrOrdinal = "BASS_SampleFree"
004010C6 |. 8B0D 90204100 MOV ECX,DWORD PTR [412090] ; |
004010CC |. 51 PUSH ECX ; |hModule => NULL
004010CD |. FF15 1CE04000 CALL DWORD PTR [<&KERNEL32.GetProcAddress>] ; \GetProcAddress
004010D3 |. A3 4C204100 MOV DWORD PTR [41204C],EAX
004010D8 |. 68 9C004100 PUSH 0041009C ; /ProcNameOrOrdinal = "BASS_SampleGetChannel"
004010DD |. 8B15 90204100 MOV EDX,DWORD PTR [412090] ; |
004010E3 |. 52 PUSH EDX ; |hModule => NULL
004010E4 |. FF15 1CE04000 CALL DWORD PTR [<&KERNEL32.GetProcAddress>] ; \GetProcAddress
004010EA |. A3 78204100 MOV DWORD PTR [412078],EAX
004010EF |. 68 B4004100 PUSH 004100B4 ; /ProcNameOrOrdinal = "BASS_ChannelSetAttribute"
004010F4 |. A1 90204100 MOV EAX,DWORD PTR [412090] ; |
004010F9 |. 50 PUSH EAX ; |hModule => NULL
004010FA |. FF15 1CE04000 CALL DWORD PTR [<&KERNEL32.GetProcAddress>] ; \GetProcAddress
00401100 |. A3 80204100 MOV DWORD PTR [412080],EAX
00401105 |. 68 D0004100 PUSH 004100D0 ; /ProcNameOrOrdinal = "BASS_Pause"
0040110A |. 8B0D 90204100 MOV ECX,DWORD PTR [412090] ; |
00401110 |. 51 PUSH ECX ; |hModule => NULL
00401111 |. FF15 1CE04000 CALL DWORD PTR [<&KERNEL32.GetProcAddress>] ; \GetProcAddress
00401117 |. A3 70204100 MOV DWORD PTR [412070],EAX
0040111C |. 68 DC004100 PUSH 004100DC ; /ProcNameOrOrdinal = "BASS_Start"
00401121 |. 8B15 90204100 MOV EDX,DWORD PTR [412090] ; |
00401127 |. 52 PUSH EDX ; |hModule => NULL
00401128 |. FF15 1CE04000 CALL DWORD PTR [<&KERNEL32.GetProcAddress>] ; \GetProcAddress
0040112E |. A3 94204100 MOV DWORD PTR [412094],EAX
00401133 |. 68 E8004100 PUSH 004100E8 ; /ProcNameOrOrdinal = "BASS_Stop"
00401138 |. A1 90204100 MOV EAX,DWORD PTR [412090] ; |
0040113D |. 50 PUSH EAX ; |hModule => NULL
0040113E |. FF15 1CE04000 CALL DWORD PTR [<&KERNEL32.GetProcAddress>] ; \GetProcAddress
00401144 |. A3 68204100 MOV DWORD PTR [412068],EAX
00401149 |. 68 F4004100 PUSH 004100F4 ; /ProcNameOrOrdinal = "BASS_SetConfig"
0040114E |. 8B0D 90204100 MOV ECX,DWORD PTR [412090] ; |
00401154 |. 51 PUSH ECX ; |hModule => NULL
00401155 |. FF15 1CE04000 CALL DWORD PTR [<&KERNEL32.GetProcAddress>] ; \GetProcAddress
0040115B |. A3 54204100 MOV DWORD PTR [412054],EAX
00401160 |. 68 04014100 PUSH 00410104 ; /ProcNameOrOrdinal = "BASS_SetVolume"
00401165 |. 8B15 90204100 MOV EDX,DWORD PTR [412090] ; |
0040116B |. 52 PUSH EDX ; |hModule => NULL
0040116C |. FF15 1CE04000 CALL DWORD PTR [<&KERNEL32.GetProcAddress>] ; \GetProcAddress
00401172 |. A3 40204100 MOV DWORD PTR [412040],EAX
00401177 |. 68 14014100 PUSH 00410114 ; /ProcNameOrOrdinal = "BASS_GetVolume"
0040117C |. A1 90204100 MOV EAX,DWORD PTR [412090] ; |
00401181 |. 50 PUSH EAX ; |hModule => NULL
00401182 |. FF15 1CE04000 CALL DWORD PTR [<&KERNEL32.GetProcAddress>] ; \GetProcAddress
00401188 |. A3 50204100 MOV DWORD PTR [412050],EAX
0040118D |. 68 24014100 PUSH 00410124 ; /ProcNameOrOrdinal = "BASS_Init"
00401192 |. 8B0D 90204100 MOV ECX,DWORD PTR [412090] ; |
00401198 |. 51 PUSH ECX ; |hModule => NULL
00401199 |. FF15 1CE04000 CALL DWORD PTR [<&KERNEL32.GetProcAddress>] ; \GetProcAddress
0040119F |. A3 44204100 MOV DWORD PTR [412044],EAX
004011A4 |. 68 30014100 PUSH 00410130 ; /ProcNameOrOrdinal = "BASS_ErrorGetCode"
004011A9 |. 8B15 90204100 MOV EDX,DWORD PTR [412090] ; |
004011AF |. 52 PUSH EDX ; |hModule => NULL
004011B0 |. FF15 1CE04000 CALL DWORD PTR [<&KERNEL32.GetProcAddress>] ; \GetProcAddress
004011B6 |. A3 8C204100 MOV DWORD PTR [41208C],EAX
004011BB |. 68 44014100 PUSH 00410144 ; /ProcNameOrOrdinal = "BASS_Free"
004011C0 |. A1 90204100 MOV EAX,DWORD PTR [412090] ; |
004011C5 |. 50 PUSH EAX ; |hModule => NULL
004011C6 |. FF15 1CE04000 CALL DWORD PTR [<&KERNEL32.GetProcAddress>] ; \GetProcAddress
004011CC |. A3 5C204100 MOV DWORD PTR [41205C],EAX
004011D1 |. 68 50014100 PUSH 00410150 ; /ProcNameOrOrdinal = "BASS_GetVersion"
004011D6 |. 8B0D 90204100 MOV ECX,DWORD PTR [412090] ; |
004011DC |. 51 PUSH ECX ; |hModule => NULL
004011DD |. FF15 1CE04000 CALL DWORD PTR [<&KERNEL32.GetProcAddress>] ; \GetProcAddress
004011E3 |. A3 58204100 MOV DWORD PTR [412058],EAX
004011E8 |. 68 60014100 PUSH 00410160 ; /ProcNameOrOrdinal = "BASS_GetCPU"
004011ED |. 8B15 90204100 MOV EDX,DWORD PTR [412090] ; |
004011F3 |. 52 PUSH EDX ; |hModule => NULL
004011F4 |. FF15 1CE04000 CALL DWORD PTR [<&KERNEL32.GetProcAddress>] ; \GetProcAddress
004011FA |. A3 6C204100 MOV DWORD PTR [41206C],EAX
004011FF |. B8 01000000 MOV EAX,1
00401204 |> 5D POP EBP
00401205 \. C3 RET

HR,

Ghandi

basstest.rar

Edited by ghandi

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...