So I use to program ASM back a long time ago in the days of DOS and win 3.1 but fell away from that in college when I turned to bio as my major.  Now I am way far behind on the new features and macros of ASM.  Here is my problem (if anyone can help that would be dandy).  I wrote a VB program for fun to implement a One-time pad encryption method.  Everything works fine and all but the encryption part is rather slow for large files.  I would like to make a .dll in assembler and call the proc from VB to run the actual encryption part but since it has been forever since I wrote assembler I don't know how to make the .dll so I can call it from VB.  Also, time was for reading and writing files you would use Int 21 (ah 3Fh and 40h respectively) to do it but now I see there are macros CreateFile, ReadFile, ect... 
What I need the Proc to do is basically this
1: I call the proc from VB with the following arguements, (Source file path, Key file path, offset of encryption and desired output file name
2:open all three (duh)
3: I write the value for encryption offset (5 bytes) followed by the 3 letter extension of the source file name to the output file (so I can restore the extension at decryption)
4: read the source file from the start and the key file starting at the offset of encryption, XOR the bytes and write them to the output file.
Pretty easy, eh?  I would think so but my brain has been fried on ASM from years of graduate lvl genetics  ;)

For decryption it would
1: Open source, key and output file
2: read source (encrypted) bytes 1-5 for offset of key encryption
3: Start reading encrypted bytes at byte 9 (to bypass the extension stored at bytes 6-8 since VB gets that for me prior to decryption anyway)
4: Start reading key bytes at offset and XOR again to decrypt.

Like I said, I have this working in Vb and it works fine except for the speed issue.  Any help would be great.  I don't expect anyone to write the whole thing for me or anything but some guidance would be appreciated.  If you want to see what the Finished VB version looks like let me know  :D


Posted on 2007-05-11 11:51:39 by Command_Prompt
OK, so while I was waiting for input I started coding the basic read and XOR section of the code (asm is very slowly coming back to me).  I still however have no clue how to pass arguments from vb to the proc, nor how to structure the file to be a dll that accepts arguments from vb in the first place (I never did that when I coded asm years ago.  Anyway here is what I have so far.  Any input would be great and if anyone knows how to make the dll to pass arguments...ummm...then I would forever be in your debt/send valentine's e-mails and such:

.Data

SourceBuffer DB 256 Dup (0)
KeyBuffer DB 256 Dup (0)
OutBuffer DB 256 Dup (0)
InFileName DB 512 Dup (0)
KeyFileName DB 512 Dup (0)
OutFileName DB 512 Dup (0)

hInFile DW
hKeyFile DW
hOutFile DW
BytesRead DB

CryptFile Proc Public
;// Open Source file to be crypted
Mov Ah, 3DH ;Open function
Mov Al, 0 ;as Read
Lea Dx, InFileName ;Specify which file to open
Int 21H ;Open
Jc _Error_Occured ;if no error occured then
Mov hInFile, Ax ;store handle

;// Open Key file to be used
Mov Ah, 3DH ;Open function
Mov Al, 2 ;as Random access (since I need to jump to offset of encryption start)
Lea Dx, InFileName ;Specify which file to open
Int 21H ;Open
Jc _Error_Occured ;if no error occured then
Mov hKeyFile, Ax ;store handle

;// Create output file to be written
Mov Ah, 3CH ;Create function
Xor Cx, Cx ;blank out cx (for file attributes)
Lea Dx, InFileName ;Specify which file to open
Int 21H ;Create
Jc _Error_Occured ;if no error occured then
Mov hOutFile, Ax ;store handle

;// Move key file's pointer to the offset required
Mov Ah, 42H ;Seek function
Mov Al, 0 ;set as offset is specified from the start of key file
Mov Bx, hKeyFile ;load key file's handle to bx
;Here Load CX:DX with offset needed in key file
Int 21H
Jc _Error_Occured ;End if error occured (file size vs offset size checked in VB)

;// Begin read and encrypt loop
_ReadAndXOR:
;// Read 512 bytes from Source file
Mov Ah, 3FH ;Read file function
Lea Dx, SourceBuffer ;With 512 byte source buffer as storage location
Mov Cx, 256 ;set length to 256
Mov Bx, hInFile ;set input file's handel to bx
Int 21H ;call int
Jc _Error_Occured ;End if error occured
Cmp Ax, 0 ;AX now holds actual bytes read, make sure data was read (in case file was an even multiple of 256)
Je _Finished_Reading_Source_File

;// Read from key, same number of btyes
;// Read 512 bytes from Source file
Mov Cx, Ax ;move the actual bytes read from AX, to CX
Mov BytesRead, Cx ;Store how many bytes were actually read to memory
Mov Ah, 3FH ;Read file function
Lea Dx, KeyBuffer ;With 512 byte source buffer as storage location
Mov Bx, hKeyFile ;set input file's handel to bx
Int 21H ;call int
Jc _Error_Occured ;End if error occured

;//XOR loop
_XORloop: ;CX should still hold actual bytes read from source
Mov Si, 0 ;zero out SI
Mov Al, SourceBuffer ;Get first byte from source file to al
Mov Ah, KeyBuffer ;Get first byte from key file to ah
Xor Ah, Al ;xor and store result in ah
Mov OutBuffer, Ah ;move XOR'd value to output string
Inc Si ;increase SI by 1
Loop _XORloop ;Loop for length of string read

;// When all bytes are read
Mov Cx, BytesRead ;Store how many bytes were actually read from memory to CX for writing length to crypted file
Mov Ah, 40H ;Set ah=write function
Mov Bx, hOutFile ;BX = output file's handle
Lea Dx, OutBuffer ;point dx to location of output string
Int 21H ;and write
Jc _Error_Occured ;
Cmp Ax, 256 ;Does # of bytes written=256?
Je _ReadAndXOR ;If not then EOF was reached, so jump to exit.  if yes then do another iteration of read and XORing


_Finished_Reading_Source_File:
_Error_Occured:
Mov Ah, 3EH ;close file function
Mov Bx, hInFile ;BX= source file handle
Int 21H ;close

Mov Ah, 3EH ;close file function
Mov Bx, hKeyFile ;BX= key file handle
Int 21H ;clsoe

Mov Ah, 3EH ;close file function
Mov Bx, hOutFile ;BX= output file handle
Int 21H ;close

Ret
CryptFile EndP
Posted on 2007-05-11 15:25:21 by Command_Prompt

You need to stop thinking in terms of 16 bit code, especially if you want to interface with modern languages like VB.

I'm not sure how you go about calling external functions from VB, but I was under the impression that VB only understands COM interfaces, which means you can't use a 'regular' DLL - it has to be a COM Server (your VB program would be the COM Client).
There are examples posted for COM stuff, Ernie and Biterider spring to mind.
Posted on 2007-05-18 00:46:00 by Homer
VB can call STDCALL funcs from any DLL with no sweat, so forget about COM :) .
But really, really, learn 32-bit asm, forget about the "int" instruction!!! Almost start from scratch.

Posted on 2007-05-18 09:58:00 by Ultrano
You can use inline assembly in VB6, just a little tricky but works

Dim MagicArray() as byte
myHex = "AABBCCED0934323424ACEB08" 'this is your executable code
ReDim MagicArray(0 To Len(myHex)/2)as byte
For i=0 To Len(myHex)/2
MagicArray(i)=Val("H&" & Mid(myHex,i*2,2))
Next i

errval=CallWindowProc(VarPtr(MagicArray(0)),0,0,0,0)

P.S: your assembly code must be self-relocateable !!!
Posted on 2007-05-19 12:49:09 by Dite
Hi guys, and sorry for resurrecting this thread.
I just thought the following link would be interesting to anyone interested on the subject...

Mixing Assembly language with Visual Basic
Posted on 2008-01-13 04:50:04 by samael
Thats an old page, but the information is basically still correct up to VB6.

VB6 can leverage any DLL that uses the STDCALL calling convention.

The language itself also has a CDECL keyword but it was unofficial and does not work in the debugger at all, and in compiled executables there is still some debate about when and where it actualy does work. It is presumed that it was an intended feature extending more compatability to the older QuickBasic (which did have a working CDECL) but was depreciated before making an official appearance.

This isnt much of an issue because STDCALL is generally more efficient than CDECL so there arent many DLL's still in service which use it. One semi-popular library which is still stuck on the legacy CDECL in its windows implementation is the GMP (GNU Multi-Precision) math library.

Some thing to keep in mind which I didnt see referenced on that page and I do not believe is officialy part of the STDCALL convention is that functions which return structures of 64-bits or less are expected to do so in EDX:EAX.

VB6 also supports type libraries and it IS recommended that you use a type library with your DLL, beause VB6 defaults to calling GetLastError() after every DLL call unless you use a type library.

Posted on 2008-01-13 08:03:30 by Rockoon