Results 1 to 12 of 12

Thread: [RESOLVED] Extract file from Res / Exe

  1. #1

    Thread Starter
    Addicted Member beic's Avatar
    Join Date
    Jun 2012
    Posts
    150

    Resolved [RESOLVED] Extract file from Res / Exe

    Hi there,

    I have some issue extracting files from Resource / Exe file.

    I have a project with resource file named Project1.res and it's contents are:

    Code:
    AAA      ICON    MOVEABLE        PRELOAD         MAIN.ICO
    
    STRINGTABLE DISCARDABLE 
    BEGIN
    	100		"1.1.0"
    END
    
    800			CUSTOM	"test1.exe"
    900			CUSTOM	"test2.exe"
    901			CUSTOM	"test2.conf"
    I can extract the binary exe files from the resource file without any issue, but the one with ID 901 is getting me some trouble while trying to extract it.

    Code:
    Call ExtractResFile("CUSTOM", 800, AppPath & "test1.exe")
    Call ExtractResFile("CUSTOM", 900, AppPath & "test2.exe")
    Call ExtractResFile("CUSTOM", 901, AppPath & "test2.conf")
    
    Private Function ExtractResFile(stResType As String, itResID As Integer, stExport2File As String) As Boolean
     On Error GoTo errh
     
     Dim byBin() As Byte
     Dim lgArray As Long
     Dim frFile As Integer
     
     frFile = FreeFile
     
     byBin = LoadResData(itResID, stResType)
     
     Open stExport2File For Output As frFile
      Do Until lgArray = UBound(byBin) + 1
       Print #frFile, (Chr$(byBin(lgArray)));
       lgArray = lgArray + 1
       DoEvents
      Loop
     Close frFile
     
     ExtractResFile = True
     
     Exit Function
     
    errh:
     Close frFile
     ExtractResFile = False
     Exit Function
    End Function
    For some reason the ID 901 after extracting will be corrupted by additional 2 bytes NULLs.

    If I compile the Project EXE and run it from the IDE it will extract it properly from it, but if I run the compiled exe, then it will add NULL string at the end of the extracted file.

    Any help would be appreciated!

    btw...the ID 901 is 500Kb textual config file, others are Binaries.
    Last edited by beic; Sep 11th, 2018 at 06:52 AM. Reason: typo

  2. #2
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,853

    Re: Extract file from Res / Exe

    Hi Beic,

    Yes, this is a known issue with extracting files from resources. Any file that's over 65520 bytes will be rounded up when it's extracted. If it's smaller, the exact file size will be extracted. If it's larger, it will be rounded UP to the nearest 4-byte boundary. In the past, I have looked at this issue in great detail, and have never found a perfect solution. It actually seems to be a problem beyond VB6, which means that using API calls can't even solve the problem.

    Here are some possible solutions, all of which involve checking to see how large the file is before deciding what to do. I'm quite confident about that 65520 byte threshold, so you need to decide whether or not your file is larger than that. Then:

    1) You might keep a hard-coded list of the size of your files larger than that, trimming them when they're extracted.

    or

    2) If there's some way to figure out what the size of the file by examining it, do that and then trim it.

    or

    3) Test and see if those extra one, two, or three bytes actually make any difference to the program opening the file.


    In the past, I've used combinations of all of those. Currently, I use either #2 or #3. The only files I stuff into resources where it makes any difference are DOCX and XLSX files. For the older DOC and XLS files, it doesn't matter. I also stuff all kinds of other file types into my resources, and haven't seen where it makes any difference. Therefore, for me, it's just these DOCX and XLSX files, and I figured out how to read those files and figure out the exact size they should be.

    Here's a block of code to fix these files. DataArray is my retrieved Byte Array from resources.

    Code:
    
        If UBound(DataArray) > 65519 Then   ' Zero based.
            s = UCase$(Right$(sSaveSpec, 5))
            Select Case s
            Case ".XLSX", ".XLTX", ".XLSM", ".XLTM", ".DOCX", ".DOTX", ".DOCM", ".DOTM"
                Select Case True
                Case DataArray(UBound(DataArray) - 21) = CByte(&H50) And _
                     DataArray(UBound(DataArray) - 20) = CByte(&H4B) And _
                     DataArray(UBound(DataArray) - 19) = CByte(&H5) And _
                     DataArray(UBound(DataArray) - 18) = CByte(&H6)             ' In this case, we're good to go.
                        '
                Case DataArray(UBound(DataArray) - 22) = CByte(&H50) And _
                     DataArray(UBound(DataArray) - 21) = CByte(&H4B) And _
                     DataArray(UBound(DataArray) - 20) = CByte(&H5) And _
                     DataArray(UBound(DataArray) - 19) = CByte(&H6)             ' Crop a byte.
                        ReDim Preserve DataArray(0 To UBound(DataArray) - 1)
                        '
                Case DataArray(UBound(DataArray) - 23) = CByte(&H50) And _
                     DataArray(UBound(DataArray) - 22) = CByte(&H4B) And _
                     DataArray(UBound(DataArray) - 21) = CByte(&H5) And _
                     DataArray(UBound(DataArray) - 20) = CByte(&H6)             ' Crop two bytes.
                        ReDim Preserve DataArray(0 To UBound(DataArray) - 2)
                        '
                Case DataArray(UBound(DataArray) - 24) = CByte(&H50) And _
                     DataArray(UBound(DataArray) - 23) = CByte(&H4B) And _
                     DataArray(UBound(DataArray) - 22) = CByte(&H5) And _
                     DataArray(UBound(DataArray) - 21) = CByte(&H6)             ' Crop three bytes.
                        ReDim Preserve DataArray(0 To UBound(DataArray) - 3)
                        '
                Case Else
                        ' Just leave it alone and hope for the best.
                End Select
            End Select
        End If
    
    

    I can provide more details if you like.

    Hope That Helps,
    Elroy

    EDIT1: Just a bit more information ... newer Office files (the ones with the X on the extension) are actually ZIP files. You can see that by opening them with something like 7Zip. They'll open right up. Therefore, as such, they've got a certain footer on them. The &H50, &H4B, &H5, &H6 is part of that footer, and it's ALWAYS a certain number of bytes from the end. Therefore, I use that information to determine the exact file size.

    EDIT2: Now, regarding your .CONF file, I've got no idea what type of file that is. Therefore, you may have to resort to option #1 above, which means that, every time it changes, you'll need to remember to alter your hard-coded size. Or, you'll have to figure out if there's some way to read it to determine the size it should be.

    EDIT3: Olaf Schmidt also once pointed out that certain ZIP files (but not Office files) may have a string-descriptor as a footer beyond those &H50, &H4B, &H5, &H6 bytes. He came up with the following code to circumvent that, but I haven't tested it:

    Code:
    
        '  Debug.Print "ByteArray-Size:"; UBound(b) + 1
        '  For i = UBound(b) - 3 To 0 Step -1
        '    If b(i) = 80 And b(i + 1) = 75 And b(i + 2) = 5 And b(i + 3) = 6 Then
        '      Debug.Print "ExpectedZipLen:"; i + 22 + b(i + 20) + 256& * b(i + 21)
        '      Exit For
        '    End If
        '  Next
    
    
    Last edited by Elroy; Sep 11th, 2018 at 07:57 AM.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  3. #3

    Thread Starter
    Addicted Member beic's Avatar
    Join Date
    Jun 2012
    Posts
    150

    Re: Extract file from Res / Exe

    Hi Elroy,

    Thank you for your quick response!

    Before I start to answer/comment to your post I will just add this quickly:

    The size of that file is exactly:

    Code:
    Size: 470 KB (481,455 bytes)
    Size on disk: 472 KB (483,328 bytes)

  4. #4
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,853

    Re: Extract file from Res / Exe

    Beic,

    If you know that'll ALWAYS be the case, just do something similar to the following after you get it into your Byte Array:

    Code:
    Redim Preserve byBin(481454)

    And that'll probably fix your problem. Notice I used 481,454 and not 481,455 because the array is ZERO-based.

    Good Luck,
    Elroy

    EDIT1: Correction, use SIZE, not Size-on-Disk. I fixed it in the above. Sorry about that. The size on disk adds size for your disk sector and/or cluster sizes (those are old FAT terms, but they still apply).
    Last edited by Elroy; Sep 11th, 2018 at 08:09 AM.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  5. #5

    Thread Starter
    Addicted Member beic's Avatar
    Join Date
    Jun 2012
    Posts
    150

    Re: Extract file from Res / Exe

    The file sizes are:

    Code:
    test1.exe 516 KB (528,384 bytes)
    test2.exe 36 KB (36,864 bytes)
    test2.conf 472 KB (483,328 bytes)
    The weird thing is that both EXE files are extracted correctly, only that CONF file has an issue.

  6. #6
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,853

    Re: Extract file from Res / Exe

    Beic,

    Please be sure and use the exact size, and not the size on disk!

    With respect to EXE files, it often makes no difference if there's an extra byte or two (or three) tagged onto the end. And, maybe their exact size just happens to be on a 4-byte boundary. It happens 1/4th of the time.

    Good Luck,
    Elroy
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  7. #7

    Thread Starter
    Addicted Member beic's Avatar
    Join Date
    Jun 2012
    Posts
    150

    Re: Extract file from Res / Exe

    No, no, no, It's fine, I understood you.

    I'm talking about the bigger EXE file and afer extraction the size stays the same, that's weird, but also good!

    Regarding CONF file, as you proposed I did it like this:

    Code:
    If itResID = 901 Then
      ReDim Preserve byBin(481454) 
    End If
    and it's extracting fine now!
    Last edited by beic; Sep 11th, 2018 at 08:32 AM. Reason: typo

  8. #8
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: [RESOLVED] Extract file from Res / Exe

    The more "dropper" programs (with embedded PE files) people write the more the antivirus scores given because a program is recognized as a VB6 program goes up. Eventually it will become impossible to run VB6 programs any more.

    You are engaged in a strongly discouraged activity.

    Another trend I have seen is antivirus detection of code that has been "hidden" as String constants in hex or base64 to be injected by a program after it starts. The score given for this is quite high, and will most likely end up being another "strike" against any VB6 program in the near future because such code injection has recently proliferated.

    Because of these exploits VB6 now has a very poor name in the security community.

  9. #9
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,853

    Re: [RESOLVED] Extract file from Res / Exe

    Dilettante,

    So, from the OS's (Windows) perspective, what's the difference in my program "dropping" a file from my resources, as compared to, say, my program creating an Access database from scratch and "dropping" it out somewhere for me to use?

    Best Regards,
    Elroy

    EDIT1: Or better yet, my program just opening some file as Open ... For Binary, and then saving persistent data I need to save. From the OS's perspective (or even any virus scanner), I don't see how there's any difference.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  10. #10

    Thread Starter
    Addicted Member beic's Avatar
    Join Date
    Jun 2012
    Posts
    150

    Re: [RESOLVED] Extract file from Res / Exe

    Quote Originally Posted by dilettante View Post
    You are engaged in a strongly discouraged activity.
    Wow, wow, wow, hold your horses just there!

    First of all you can't accuse me for anything, second I developing a front end GUI for AVR microcontroller flasher, so I don't want to make a setup file for it and I decided to embed those EXEs and support files!

    Just my two cents.

    Regards,
    Viktor

  11. #11
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: [RESOLVED] Extract file from Res / Exe

    I wasn't accusing you of anything except poor practices. Practices that are causing VB6 application users more and more grief.

    Even if your program is completely innocent, use of malware techniques gives VB6 programs a black eye as a group.

  12. #12

    Thread Starter
    Addicted Member beic's Avatar
    Join Date
    Jun 2012
    Posts
    150

    Re: [RESOLVED] Extract file from Res / Exe

    These kind of things can be achieved in ANY programming language.

Tags for this Thread

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