Results 1 to 5 of 5

Thread: Binary strings from anything

  1. #1

    Thread Starter
    VB6, XHTML & CSS hobbyist Merri's Avatar
    Join Date
    Oct 2002
    Location
    Finland
    Posts
    6,654

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

  2. #2
    New Member
    Join Date
    Jun 2007
    Location
    South Africa
    Posts
    8

    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

  3. #3

    Thread Starter
    VB6, XHTML & CSS hobbyist Merri's Avatar
    Join Date
    Oct 2002
    Location
    Finland
    Posts
    6,654

    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.

  4. #4
    New Member
    Join Date
    Jun 2007
    Location
    South Africa
    Posts
    8

    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

  5. #5

    Thread Starter
    VB6, XHTML & CSS hobbyist Merri's Avatar
    Join Date
    Oct 2002
    Location
    Finland
    Posts
    6,654

    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
  •  



Click Here to Expand Forum to Full Width