Jump to content
Tuts 4 You

How to build a lib from a dll?


LCF-AT

Recommended Posts

Hello again,

at the moment I try to find out how to build libs from dll files.I found some infos on internet how to do it but I don't get it work and I don't know why and what the problem is.Infos about building a lib I found on that source...

http://win32assembly.programminghorizon.com/importlib.html

https://adrianhenke.wordpress.com/2008/12/05/create-lib-file-from-dll/

...I did these steps and got a lib file of my xy dll and did add it into my asm include lib code but if I try to use any export API then I always get a unresolved external error of the APIs I wanna use. :( The question what I do wrong if I did anything wrong and how to fix it.So its the first time I try to create a lib of a dll so I think I have done anything wrong and now I need some help to find the problem reason and a fix.So can anyone help me and tell again how to do it correctly on any tiny example / dll etc?Would be nice if you could.

Thank you

  • Like 1
Link to comment

I had same problem recently. It is weird that you cannot import function in C/C++ by givin dll name + api name.

 

Edit: I actually followed the tut from second link (dumpbin and lib from visual studio) and IT WORKS WONDERS! It generated .def .exp and .lib file from external dll!

Edited by Pancake
Link to comment

If u have an existing .dll & all u want is to make a .lib/.a file to link against the .dll, not a static compile, then use dumpbin & lib like in the links

if the .dll u are trying to link against was compiled in C or C++, then in ur forward declaration in the .asm file u -have- to write C, or else it'll give u an unresolved external

MyStaticFunction PROTO C, :DWORD ; this is invokeable

possibly the compiler/linker used to create the .dll may have added/removed an underscore, so u can also try to add or remove a "_" in the PROTO forward declaration. can u give more info about ur .dll?

edit- would need to know more about ur specific .dll lcf, namely compiler/linker used to build it. there's a lot of stuff that could be wrong. it's also probably easier to just use loadlib/getprocaddress

Edited by simple
update
Link to comment

Hi again thanks for the answers so far.

Ok I did you what you said and enteres C, after PROTO.So on the first view it seems to work but now I get a strange message about dll wasn't found!?!So it means the file was compiled now (good) but isn't working now because of that dll message.I have the dll in same folder also I tried to put it into system32 folder but still not working.Hmm.So I can see the dll name & APIs in file if I load it into LordPE for example.Maybe still something wrong.

Ok listen.My goal was it to create libs for 2 dlls called bassvideo.dll & bass.dll which you can find here..

http://www.un4seen.com/

...I just try to build a own little video-stream-player + trying later to make this videoplayer stdout able too (don't know yet how to do it) etc.I wrote already a own code so far which works but in this code I use a bad coding method using these exports of bass & bassvideo dlls (LLA & GPA / push xy call exports etc you know).I would like to use invoke commands with parameters as usually like other APIs & structs etc you know.

PS: One extra question.Does anyone know how to play mp4 files?My system does not play them from alone and FFDShow does not popup (have enabled H264 & AAC) if I try to play such files in my build player (others working flv,avi,wmv etc).

greetz

Link to comment

U r doing this backwards. i used bass audio lib in a project before and there's already .lib distro'd. There's no need to make ur own - Everything u need is in folder "c" - the .dll & .lib

on their site there's also some masm code samples, none built for me got various errors on ml. i wrote this tho - heres a sample how to play an audio file. dont know about video

I saw ur question about stdout in ur other thread too, ur problem is ur not writing to stdout dude, search "WriteFile stdout", or "stdout piping", there's various ways to do it.  

F$%$%ing board is still messing up my code formatting.

.386p
.model	flat, stdcall
option	casemap: none

include \masm32\include\masm32.inc
include \masm32\include\msvcrt.inc
include \masm32\macros\macros.asm	
include \masm32\include\kernel32.inc

includelib \masm32\lib\masm32.lib
includelib \masm32\lib\msvcrt.lib
includelib \masm32\lib\kernel32.lib
includelib bass.lib

Main                  Proto
BASS_GetVersion       Proto
BASS_Init             Proto :Dword,:Dword,:Dword,:Dword,:Dword
BASS_StreamCreateFile Proto :Dword,:Dword,:Qword,:Qword,:Dword
BASS_ChannelPlay      Proto :Dword,:Dword
BASS_Free             Proto 
BASS_ErrorGetCode     Proto

.data


.data?
.code
start:
Main Proc
        Local Device       :Dword 
        Local Frequency    :Dword
	    Local Arg3         :Qword
	    Local Arg4         :Qword
	    Local StreamHandle :Dword
	    Invoke crt_memset, Addr Arg3, 0, 8
	    Invoke crt_memset, Addr Arg4, 0, 8

        Mov Device,       -1h
	    Mov Frequency,    021534h  

        invoke BASS_GetVersion
  
        Shr Eax, 10h
  
        .If Ax != 204h

                invoke crt_printf, SADD('Incorrect DLL')
      
        .Else

                invoke crt_printf, SADD('Playing audio file...')
	   
	            Invoke BASS_Init, Device, Frequency, 0, 0, 0
	   
	            .If (Eax == 0)
		
					Invoke BASS_ErrorGetCode
			
					Invoke crt_printf, SADD('Error BASS_Init() %i'), Eax
			
				.Else
	
	                Invoke BASS_StreamCreateFile, 0, SADD('playme.mp3'), Arg3, Arg4, 0
			
				.If (Eax == 0)
		
			    	Invoke BASS_ErrorGetCode
			
			    	Invoke crt_printf, SADD('Error BASS_StreamCreateFile() %i'), Eax
			
				.Else
			
					Mov StreamHandle, Eax
				
					Invoke BASS_ChannelPlay, StreamHandle, 0
			
				.Endif
			
				Invoke BASS_Free
			
        .Endif
	
    .Endif
 
    Invoke ExitProcess, 0 
Main endp
end start

 

Edited by simple
code
Link to comment

There are two approches to use a third-party .DLL without .h and .lib files:
1) run-time dynamic linking
As simple said, the easier way is LoadLibrary, GetProcAddress, and FreeLibrary.
2) load-time dynamic linking
You have to create the .h(.inc in asm) and .lib files on your own.
Useful links:
Creating Import Library from a DLL with Header File - CodeProject
How To Create 32-bit Import Libraries Without .OBJs or Source

PS: My favarite player is MPlayer. You can download source code at: http://www.mplayerhq.hu/
Or the binaries on Windows at: http://oss.netfarm.it/mplayer/

Regards,

MistHill

Link to comment

To call functions from bassvideo.dll in masm, use dumpbin/lib to create .lib, then u have to use PROTO C in forward decalaration. bass.dll only needs PROTO. Unlike bass.dll, bassvideo.dll isn't distro'd w/.lib because in the .cpp file they use function pointers and don't link manually. Not sure why u getting the .dll error because this works fine for me. this project has a lot of documentation & samples so I think u need to look harder in the "c" folders of both bassaudio & bassvideo.

Link to comment

Hi again,

ok wait now I am little confused.Now I did some downloads from that site and see it now that there is a bass.lib (I got any other package by friend).Good so far but I want to make a video player not only a audio player you know.So for videos I need to use the bassvideo.dll you can DL here..

http://www.un4seen.com/filez/6/BassVideo_2.4.1.2.zip

...and in this set you can find bassvideo.dll + chm file etc but no bassvideo.lib file which I could use.So I mean I need to init the bass.dll and then using bassvideo APIs to play / handle videos.Ok I have test now again about the bassvideo.dll to make a lib.So it seems I did something wrong and created a basevideo.lib instead of basssvideo.lib (some rename error). :) Great!Ok now it works and I can compile that file.Sorry was my fault again.

Question about stdout.So do you have a example about it what I could understand?I also mean what check I have to write in my player source to see whether stdout was requested or not and what to do then?So you know VLC & MPC-HC player are also stdout able I can use with other CMD tools to pipe streams into without to save any video datas etc so this I wanna also have in my player so that I can use my player too with such tools you know.Maybe you can help a little if I can ask you a little (sorry).

Thanks again so far guys.

Link to comment

Yeah u just need to learn to work w/c & c++ projects.

I don't think bassvideo.dll is very good, in unseen forums people were saying its buggy, breaks, etc & there's some new un4seen project that replaces it.

What don't u understand about stdout - what is ur question? Its pretty straightforward, take ur video stream bytes and fprintf, printf/flush, writefile(), etc them to stdout. try to post your code that gives u problems.

also, pancake, u should be able to get an idea more or less what the c++ class looks like when it's instantiated in the binary. i think ida has a plugin to automate that, hex kings or something.

 

Link to comment

I know exactly how classes are translated into asm. I am fully aware of fact that the member variables are not exported. What i mean is i have dll consisting of shit ton of exported classes with exported methods and i will not type MANUALLY class __declspec(dllimport) bla bla { all methods } for every class. I was lookin for automated way to create nice file to include

Im pretty sure it wouldnt be that hard to make parser which would translate the unmangled exports into .h file tho... :)

 

I actually took quick look at "dbghelp" unmangler. It creates very good result, like:

public: __thiscall className::methodName(type, type)

 

So it seems its not that hard :)

Edited by Pancake
Link to comment

thats not a reliable way (undname, UnDecorateName, DbgHelp, etc) - read Qt's docs for a lot of easy ways to make all that useless. 

theres no point & click tools to generate project files from .dll's. if u have experience coding what u r ripping - it'll be easy - if not, ur in for a world of pain (at least for c++ classes)

 

 

Link to comment

Hi again,

anyway so at the moment I try to use bassvideo.dll for testing to build any videoplayer for my taste.Maybe bassvideo.dll is buggy but I don't know how to build a videoplayer without that you know.

About stdout: So the first problem I have is that I don't understand how it does work or how I have to handle it you know?

Example: Normaly I do use VLC or MPC-HC player for stdout in connection with other stream tools who do send the stream datas to stdout like rtmpdump or livestreamer for example.

Example: to file...
rtmpdump -r "rtmp://live.hkstv.hk.lxdns.com/live/hks" -o "Video.flv"
or stdout to player
rtmpdump -r "rtmp://live.hkstv.hk.lxdns.com/live/hks" | "C:\Programme\MPC-HC\mpc-hc.exe" -

Now I need to know how the player does check whether it was requested by other tool and whether it was requested to read in stdout mode and then I also wanna know how then to read from stdout and how to send the data stream to play API to play that stream instead of a normal file like "C:\video1.flv" etc you know?The question is how I can do that.So I can't debug the player itself in that execution mode to see what the player does.Maybe you do understand me now what I want.

greetz

Link to comment
Quote

rtmpdump -r "rtmp://live.hkstv.hk.lxdns.com/live/hks" -o "Video.flv"

there's already source code samples to do exactly this (librtmp is well known library)

Quote

rtmpdump -r "rtmp://live.hkstv.hk.lxdns.com/live/hks" | "C:\Programme\MPC-HC\mpc-hc.exe" -

For this functionality, in rtmpdump.c (rtmpdump is open source) check Download() function, line 444. Notice argument - bStdOutMode...

Quote

Now I need to know how the player does check whether it was requested by other tool and whether it was requested to read in stdout mode and then I also wanna know how then to read from stdout and how to send the data stream to play API to play that stream instead of a normal file like "C:\video1.flv" etc you know?The question is how I can do that.So I can't debug the player itself in that execution mode to see what the player does

theres no need to debug the player dude, it's open source. why debug if u have source??

"to read in stdout mode", i think u mean read from stdin (stdout is for program sending, stdin is for program receiving), search engine "read from stdin masm"..

for playing .flv files, in whole or i part - look in demo.cpp, around lines 150 & 190, BassVideo_StreamCreateFile() should be able to play .flv stream bytes in buffer chunks of X bytes. next time post your problematic code.

 

 

Link to comment

Hello again and thanks for your answer again.

Ok listen.Maybe I do explain what I want wrong or maybe I don't understand what I want or anyhing like this.Sorry about this simple.About debugging the player I meant the player who does play the stream like VLC or MPC so check out what the player does IF it was startet by other extern tool like rtmpdump etc.So in my mind I think the player itself must check this whether to read from buffer (stdin etc) or from file (videoxy.flv etc).Thats the first problem and I don't know how to check this.So you mean rtmpdump does send stream datas to stdout (if player was choosen as output) ok and now my player has to read from stdin yes and then sending the buffer to the bassvideo API who can play this.Just tell me if I think wrong again or something.

Ok I found a samle code / app in masm calling PipeSample.zip and there it does read from stdin...

invoke  GetStdHandle,STD_INPUT_HANDLE

invoke  ReadFile,hInput,esi,BUFSIZE,ADDR dwRead,NULL

Now I need call here bassvideo_BassVideo_StreamCreateFile
or
BassVideo_StreamCreateFileMem?

...ok I have test a little with GetStdHandle & STD_INPUT_HANDLE so this I could use as check (if 0 = play from file or if 3 = handle = read from stdin) or?

PS: Problem is I don't have no problem code so far so I just wrote my code to play video files from file with path pointer to video file + using BassVideo_StreamCreateFile.I didn't wrote anything about reading stdin yet so thats the problem I have and don't know how to do it exactly you know.Sorry again.

greetz

Link to comment

Hi again,

ok now I have this...

invoke  GetStdHandle,STD_INPUT_HANDLE
.if eax != 0h	    
mov STDIN, eax
invoke CreateThread,0,0,addr STDOUTREAD,0,0,0
.endif

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
STDOUTREAD proc

local ISPLAY:DWORD

mov ISPLAY, 0h
@TOP:
invoke Sleep,2000

mov     esi,OFFSET STDBUFFER
@@:
invoke  ReadFile,STDIN,esi,sizeof STDBUFFER,ADDR dwRead,NULL
test    eax,eax
je      @f
cmp     dwRead,0
je      @f
mov     eax,dwRead
    
    
.if  ISPLAY == 0h   
		    
		    push 0 
		    push offset VideoAction
		    push 0
		    push 0
		    push 0
		    push sizeof STDBUFFER
		    push offset STDBUFFER;NEWPATHBUFFER
	            call BassVideo_StreamCreateFileMem 
                    push eax
                    call BassVideo_Play
mov ISPLAY, 1h    
.endif    

jmp     @b
@@:

jmp @TOP

	Ret
STDOUTREAD endp

...no idea whether its right so but isn't working so far.So it reads now stdin but something I do wrong with that StreamCreateFileMem API.In the description I see something with QWORD so what to push there as size?Is that way above anyhow correctly or not?

BassVideo_StreamCreateFileMem

function BassVideo_StreamCreateFileMem(data :Pointer; datalength : QWORD; MediaType, Flags, BassFlags : DWORD; CallBackProc : VIDEOPROC; user : Pointer): DWORD; stdcall;

greetz

Link to comment

Stop apologizing !

Look in rtmpdump.c, it reads from socket then writes to stdout in certain size chunks, not all at once. So ur program reading stdin will need to loop over it, not read just once.

I started trying to make a sample code to do this lcf, and the only documentation I found was  written in English I can't even understand & some half written crap samples w/bassvideo.dll.

libvlc is. vlc player & mpc are both open source, search for it. libvlc also plays .mp4. libvlc has good documentation, various code samples to stream .flv's & appears to be a lot more widely used than bassvideo.dll. 

Link to comment

Hi again,

so I tried to loop readfile API to read from stdin but the problem is the readfile API only works on time if I do change the buffer address (adding the numer of bytes which was read lpNumberOfBytesRead and sub the lpNumberOfBytesRead from size).If I keep it always same then it reads. :( Problem is also I can't debug it to check what the problem could be.If I only call readfile API one time then BassVideo_StreamCreateFileMem & BassVideo_Play after then I get one frame of the video to see in my player....so somehow it works but I still do something wrong.

So I get the stream to play for a few seconds only now so I wrote this....

Here my code at top on WM_INITDIALOG

STDBUFFER db 180000 dup (?)


invoke  GetStdHandle,STD_INPUT_HANDLE
.if eax != 0h	    
mov STDIN, eax
invoke CreateThread,0,0,addr STDOUTREAD,0,0,0
invoke CloseHandle,eax	    
invoke TESTER
.endif
......


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
STDOUTREAD proc
mov esi ,offset STDBUFFER
mov edi, sizeof STDBUFFER

@TOP:   
invoke  ReadFile,STDIN,esi,edi,ADDR dwRead,NULL
cmp eax,0h
je OUT1
mov eax, dwRead
add esi, eax
sub edi, eax
jmp @TOP

OUT1:
ret
STDOUTREAD endp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
TESTER proc

.if  ISPLAY == 0h   

push 0
push offset VideoAction
push 0
push 0
push 0
push 0		    
push sizeof STDBUFFER
push offset STDBUFFER
call BassVideo_StreamCreateFileMem
mov BHANDLE, eax
push BHANDLE
call BassVideo_Play 
mov ISPLAY, 1h  

.endif 

Ret
TESTER endp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

....problem is the readfile API again.It only read some bytes and then nothing anymore.If I don't add the read bytes & size at readfile API then rtmpdump does run normaly go on but the the player does nothing play so bytes get overwritten.Strange thing.

Sounds nice that you create a example so I hope to check out how it has to work correctly.Thanks again.

greetz

Link to comment

Hi its me again,

so today I checked the code again and found something what could be the problem using BassVideo_StreamCreateFileMem API.So I get videostream from internet running in my player with that API + reading from stdin but the problem is that it only plays the buffer without to update and then the playing does stop.If I let read from stdin into buffer for 20 seconds and do then call BassVideo_StreamCreateFileMem & BassVideo_Play then the stream also runs only 20 seconds.If I now press on my slider then the video starts again from the beginning but this time it plays longer so it read now more bytes from buffer as before.Now I am not sure what to do to get the stream played constantly without to stop and without to start from begining again.

greetz

Link to comment

Hi again,

any progress simple?

Or did you check again the BassVideo stuff etc?If you like I can send your my player source with a example bat file what does execute my player with a stream what does play for xy seconds if it helps etc.All in all I stuck and come not forward anymore and some help would be welcome.

greetz

Link to comment

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...