|
-
Jun 13th, 2007, 05:43 PM
#1
Binary strings from anything
I started doodling around with this, wanting to create a function that can take anything in and return a binary representation of the data. To let anything to be passed, one has to use a Variant. So, I did some of my magic tricks and ended up with the following code:
Code:
' Module1.bas
Option Explicit
Public Type Byte128
Block(15) As Byte
End Type
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByRef lpvDest As Any, ByRef lpvSrc As Any, ByVal cbLen As Long)
Private Declare Function GetCurrentProcessId Lib "kernel32" () As Long
Private Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As String) As Long
Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long
Private Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function WriteProcessMemory Lib "kernel32" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Private Sub ReplaceSub(ByVal AddressOfDest As Long, ByVal AddressOfSrc As Long)
Dim larJMPASM(1) As Long
Dim lngProcessHandle As Long, lngBytesWritten As Long
' get a handle for current process
lngProcessHandle = OpenProcess(&H1F0FFF, 0&, GetCurrentProcessId)
' if failed, we can't do anything
If lngProcessHandle = 0 Then Exit Sub
' check if we are in the IDE
If App.LogMode = 0 Then
' get the real locations of the procedures
CopyMemory AddressOfDest, ByVal AddressOfDest + &H16&, 4&
CopyMemory AddressOfSrc, ByVal AddressOfSrc + &H16&, 4&
End If
' set ASM JMP
larJMPASM(0) = &HE9000000
' set JMP parameter (how many bytes to jump)
larJMPASM(1) = AddressOfSrc - AddressOfDest - 5
' replace original procedure with the JMP
WriteProcessMemory lngProcessHandle, ByVal AddressOfDest, ByVal VarPtr(larJMPASM(0)) + 3, 5, lngBytesWritten
' close handle for current process
CloseHandle lngProcessHandle
End Sub
Public Function GetBinaryString(ByRef Value As Variant) As String
ReplaceSub AddressOf Module1.GetBinaryString, AddressOf Module1.GetBinaryStringREAL
GetBinaryString = GetBinaryString(Value)
End Function
Public Function GetBinaryStringREAL(ByRef Value As Byte128) As String
Static blnString As Boolean, ByteString(255) As String * 8, SpaceString(15) As String
Dim lngA As Long, lngB As Long, lngPos As Long, strOut As String
If Not blnString Then
For lngA = 0 To 255
ByteString(lngA) = _
ChrW$(48 - ((128 And lngA) = 128)) & _
ChrW$(48 - ((64 And lngA) = 64)) & _
ChrW$(48 - ((32 And lngA) = 32)) & _
ChrW$(48 - ((16 And lngA) = 16)) & _
ChrW$(48 - ((8 And lngA) = 8)) & _
ChrW$(48 - ((4 And lngA) = 4)) & _
ChrW$(48 - ((2 And lngA) = 2)) & _
ChrW$(48 - ((1 And lngA) = 1))
Next lngA
For lngA = 0 To 15
SpaceString(lngA) = Space$((16 - lngA) * 8)
Next lngA
blnString = True
End If
For lngA = 0 To 15
If Value.Block(lngA) <> 0 Then Exit For
Next lngA
If lngA < 16 Then
lngB = lngA - (lngA Mod 8) + (7 - (lngA Mod 8))
strOut = SpaceString(lngB)
lngPos = 1
For lngA = lngB To 15
lngB = lngA - (lngA Mod 8) + (7 - (lngA Mod 8))
Mid$(strOut, lngPos, 8) = ByteString(Value.Block(lngB))
lngPos = lngPos + 8
Next lngA
GetBinaryStringREAL = strOut
End If
End Function
And some code to check it out:
Code:
' Form1.frm
Option Explicit
Private Sub Command1_Click()
Dim strTest As String
strTest = GetBinaryString(1)
Debug.Print strTest, Len(strTest)
End Sub
This doesn't work yet as I planned to, but it is somewhat a beginning to get it all working. Variant is a major problem, because it causes some oddities with handling of the data. There are also some other problems, such as the bit order (I'm sure I'm not doing my math right in there with lngB).
Anyways, the challenge is to... create a function that can take any variable in and give a binary representation of that given data.
(Note: how to understand the above description is up to you... if you want it to start handling String data character by character, then make it work with that... but be warned that you might make things too complicated if you start working that way, because you need to take every datatype into account.)
-
Jun 26th, 2007, 01:47 PM
#2
New Member
Re: Binary strings from anything
Hi there,
Not sure what you are trying to do, but I would guess you are trying to do this:
If the users enters the value 1, then in binary you display 1 (maybe left padded to the nearest byte, so 0000 0001).
If the user enters 28 then 0001 1100?
If the user enters 'A' (value 65) then display 0100 0001.
Is this correct? If so please let me know because it appears that you have far too much code there.
Regards,
John
-
Jun 26th, 2007, 04:12 PM
#3
Re: Binary strings from anything
No, that isn't the only thing. At the moment it shows the contents of a Variant datatype as a binary representation. The basic idea would be to give in any datatype and it would show the binary representation of that datatype, although as such it isn't very useful in the end (except maybe in some special cases of debugging).
It isn't only for a simple conversion of a number or a first character of a string.
-
Jun 27th, 2007, 02:07 AM
#4
New Member
Re: Binary strings from anything
Hi,
I didn't mean to imply that we only convert the first character of a string, I meant we convert the entire string in that way.
I wouldn't think that a variant is a good type to use. The reason I say that is because you need to decide, based on the type of data coming in, how to handle the conversion (this is where c++ with overloaded functions would be very handy).
So, If it is a string, we would need to loop through every character and convert it as mentioned in the previous post. This is not difficult, but would be time consuming on large files of text as you would first need to get the character value then do the conversion per character, ie ConvertToBin(Asc("A")). This loop would take pretty long.
For integers and longs, etc, you just do a conversion of the value of the entire number, rather than converting each digit (so, decimal value 12 becomes 0000 1100 as opposed to 0000 0001 0000 0010).
For other datatypes, I guess you could handle it similar to strings where you convert to the numeric value using the built in function Asc("x"), then send that to your binary converting functions.
Do I have the wrong end of the stick here or am I sort of on the right track?
Regards,
John
-
Jun 27th, 2007, 02:45 AM
#5
Re: Binary strings from anything
Variant tells you the datatype of the incoming data in the few highest bits, so this would allow to make a generic function that works for anything if you just check what you're getting.
As for Asc (or the slightly faster version AscW), it shouldn't be used at all when speed becomes a concern. The issue with strings is that characters are basically Integer data, so you can't expect only to have 8-bit range. They may as well be 16-bit Unicode.
As for value 12, it would be rather automatic for it to become 0000 1100. It would only be far more work to start separating each number.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|