Results 1 to 13 of 13

Thread: [VB6] - Store data to EXE.

  1. #1

    Thread Starter
    PowerPoster
    Join Date
    Feb 2015
    Posts
    2,671

    [VB6] - Store data to EXE.

    Hello everyone!
    There are times when you want to save the data after completion of the program, but did not want to have external dependencies, registry entries, etc. However you can store the data in your EXE. Unfortunately, Windows doesn't allow to write into the running EXE (i don't consider NTFS streams), and any attempt of the writing will be rejected with the ERROR_ACCESS_DENIED error. Although if the process is complete it can be performed by another process. Here is the way I decided to choose.
    Firstly, you'd run cmd.exe with the suspended state. Further you'd create code that will be injected to it and will change the resources of our EXE. Then you'd run this code. This code waits for termination of our process and then rewrites the needed data (you've passed them to there). Eventually it is terminated.
    In order to simplify the code (it only needs single form) i decide to make it in assembler. It is simpler and requires less code (source is included). Because the code is published especially for the review and test, it doesn't perform any synchronizations.
    Code:
    ' Store data to EXE
    ' © Krivous Anatolii Anatolevich (The trick), 2014
    ' Writing is performed only after process termination
    
    Option Explicit
    
    Private Type STARTUPINFO
        cb              As Long
        lpReserved      As Long
        lpDesktop       As Long
        lpTitle         As Long
        dwX             As Long
        dwY             As Long
        dwXSize         As Long
        dwYSize         As Long
        dwXCountChars   As Long
        dwYCountChars   As Long
        dwFillAttribute As Long
        dwFlags         As Long
        wShowWindow     As Integer
        cbReserved2     As Integer
        lpReserved2     As Long
        hStdInput       As Long
        hStdOutput      As Long
        hStdError       As Long
    End Type
    
    Private Type PROCESS_INFORMATION
        hProcess        As Long
        hThread         As Long
        dwProcessId     As Long
        dwThreadId      As Long
    End Type
    
    Private Type ThreadData
        hParent         As Long
        lpFileName      As Long
        lpRsrcName      As Long
        lpData          As Long
        dwDataCount     As Long
        lpWFSO          As Long
        lpCH            As Long
        lpBUR           As Long
        lpUR            As Long
        lpEUR           As Long
        lpEP            As Long
    End Type
    
    Private Declare Function CloseHandle Lib "kernel32" ( _
                             ByVal hObject As Long) As Long
    Private Declare Function CreateProcess Lib "kernel32" _
                             Alias "CreateProcessW" ( _
                             ByVal lpApplicationName As Long, _
                             ByVal lpCommandLine As Long, _
                             lpProcessAttributes As Any, _
                             lpThreadAttributes As Any, _
                             ByVal bInheritHandles As Long, _
                             ByVal dwCreationFlags As Long, _
                             lpEnvironment As Any, _
                             ByVal lpCurrentDirectory As Long, _
                             lpStartupInfo As STARTUPINFO, _
                             lpProcessInformation As PROCESS_INFORMATION) 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 DuplicateHandle Lib "kernel32" ( _
                             ByVal hSourceProcessHandle As Long, _
                             ByVal hSourceHandle As Long, _
                             ByVal hTargetProcessHandle As Long, _
                             lpTargetHandle As Long, _
                             ByVal dwDesiredAccess As Long, _
                             ByVal bInheritHandle As Long, _
                             ByVal dwOptions As Long) As Long
    Private Declare Function GetCurrentProcess Lib "kernel32" () As Long
    Private Declare Function VirtualAllocEx Lib "kernel32.dll" ( _
                             ByVal hProcess As Long, _
                             lpAddress As Any, _
                             ByVal dwSize As Long, _
                             ByVal flAllocationType As Long, _
                             ByVal flProtect As Long) As Long
    Private Declare Function WriteProcessMemory Lib "kernel32" ( _
                             ByVal hProcess As Long, _
                             ByVal lpBaseAddress As Long, _
                             lpBuffer As Any, _
                             ByVal nSize As Long, _
                             lpNumberOfBytesWritten As Long) As Long
    Private Declare Function GetMem4 Lib "msvbvm60" ( _
                             src As Any, _
                             dst As Any) As Long
    Private Declare Function VirtualFreeEx Lib "kernel32.dll" ( _
                             ByVal hProcess As Long, _
                             lpAddress As Any, _
                             ByVal dwSize As Long, _
                             ByVal dwFreeType As Long) As Long
    Private Declare Function CreateRemoteThread Lib "kernel32" ( _
                             ByVal hProcess As Long, _
                             lpThreadAttributes As Any, _
                             ByVal dwStackSize As Long, _
                             ByVal lpStartAddress As Long, _
                             lpParameter As Any, _
                             ByVal dwCreationFlags As Long, _
                             lpThreadId As Long) As Long
    Private Declare Function FindResource Lib "kernel32" _
                             Alias "FindResourceW" ( _
                             ByVal hInstance As Long, _
                             ByVal lpName As Long, _
                             ByVal lpType As Long) As Long
    Private Declare Function LoadResource Lib "kernel32" ( _
                             ByVal hInstance As Long, _
                             ByVal hResInfo As Long) As Long
    Private Declare Function LockResource Lib "kernel32" ( _
                             ByVal hResData As Long) As Long
    Private Declare Function SizeofResource Lib "kernel32" ( _
                             ByVal hInstance As Long, _
                             ByVal hResInfo As Long) As Long
    Private Declare Sub CopyMemory Lib "kernel32" _
                             Alias "RtlMoveMemory" ( _
                             Destination As Any, _
                             Source As Any, _
                             ByVal Length As Long)
    
    Private Const STARTF_USESHOWWINDOW      As Long = &H1
    Private Const SW_HIDE                   As Long = 0
    Private Const MEM_COMMIT                As Long = &H1000&
    Private Const MEM_RESERVE               As Long = &H2000&
    Private Const MEM_RELEASE               As Long = &H8000&
    Private Const PAGE_EXECUTE_READWRITE    As Long = &H40&
    Private Const INFINITE                  As Long = -1&
    Private Const MAX_PATH                  As Long = 260
    Private Const RT_RCDATA                 As Long = 10&
    Private Const CREATE_SUSPENDED          As Long = &H4
    Private Const DUPLICATE_SAME_ACCESS     As Long = &H2
    Private Const ResName                   As String = "TRICKRESOURCE" & vbNullChar    ' Only capital letters
    
    ' // Procedure load data from EXE
    Private Sub LoadFromEXE()
        Dim hRes As Long, hMem As Long, ptr As Long, l As Long, Msg As String
        
        hRes = FindResource(0, StrPtr(ResName), RT_RCDATA)
        
        If hRes Then
            hMem = LoadResource(0, hRes)
            If hMem Then
                l = SizeofResource(0, hRes)
                If l Then
                    ptr = LockResource(hMem)
                    GetMem4 ByVal ptr, l
                    Msg = Space(l \ 2)
                    CopyMemory ByVal StrPtr(Msg), ByVal ptr + 4, l
                    txtData.Text = Msg
                End If
            End If
        End If
        
    End Sub
    
    ' // Procedure store data to EXE
    Private Sub StoreToExe()
        Dim hLib As Long
        Dim td As ThreadData, ts As Long, path As String, pi As PROCESS_INFORMATION, si As STARTUPINFO, hProc As Long, lpDat As Long, pt As Long
        Dim Code() As Byte, Data() As Byte, ret As Long, thr As Long, otd As Long
        
        ' // Get the Kernel32 handle
        hLib = GetModuleHandle("kernel32")
        If hLib = 0 Then MsgBox "Error": Exit Sub
        
        ' // Get the functions addresses
        td.lpWFSO = GetProcAddress(hLib, "WaitForSingleObject")
        td.lpCH = GetProcAddress(hLib, "CloseHandle")
        td.lpBUR = GetProcAddress(hLib, "BeginUpdateResourceW")
        td.lpUR = GetProcAddress(hLib, "UpdateResourceW")
        td.lpEUR = GetProcAddress(hLib, "EndUpdateResourceW")
        td.lpEP = GetProcAddress(hLib, "ExitProcess")
        
        path = App.path & "\" & App.EXEName & ".exe" & vbNullChar
        
        ' // Create the machine code
        CreateCode Code
        
        ' // Calculate size of the needed memory
        ts = LenB(path) + LenB(ResName) + (UBound(Code) + 1) + LenB(txtData.Text) + Len(td) + 4
        
        si.cb = Len(si)
        si.dwFlags = STARTF_USESHOWWINDOW
        si.wShowWindow = SW_HIDE
        
        ' // Launch "victim" (CMD.EXE)
        If CreateProcess(StrPtr(Environ("ComSpec")), 0, ByVal 0&, ByVal 0&, False, CREATE_SUSPENDED, ByVal 0, 0, si, pi) = 0 Then
            MsgBox "error": Exit Sub
        End If
        
        ' // Get handle of the our process for CMD process
        hProc = GetCurrentProcess()
        DuplicateHandle hProc, hProc, pi.hProcess, td.hParent, 0, False, DUPLICATE_SAME_ACCESS
        
        td.dwDataCount = LenB(txtData.Text) + 4        ' Размер данных
        
        ' // Allocate memory in the CMD
        lpDat = VirtualAllocEx(pi.hProcess, ByVal 0, ts, MEM_COMMIT Or MEM_RESERVE, PAGE_EXECUTE_READWRITE)
        
        If lpDat = 0 Then
            MsgBox "Error": CloseHandle pi.hThread: CloseHandle pi.hProcess
            VirtualFreeEx pi.hProcess, ByVal lpDat, 0, MEM_RELEASE
            Exit Sub
        End If
        
        ' // Ok, all is ready for the writing to cmd
        ' // Create buffer with data
        ReDim Data(ts - 1)
        
        ' // Copy the file name of our process
        CopyMemory Data(pt), ByVal StrPtr(path), LenB(path)
        td.lpFileName = lpDat + pt: pt = pt + LenB(path)
        ' // Copy the name of the resource
        CopyMemory Data(pt), ByVal StrPtr(ResName), LenB(ResName)
        td.lpRsrcName = lpDat + pt: pt = pt + LenB(ResName)
        ' // Copy the data of the resource
        GetMem4 LenB(txtData.Text), Data(pt)          ' Размер
        CopyMemory Data(pt + 4), ByVal StrPtr(txtData.Text), LenB(txtData.Text)
        td.lpData = lpDat + pt: pt = pt + LenB(txtData.Text) + 4
        ' // Copy the structure to buffer
        CopyMemory Data(pt), td, Len(td): otd = pt: pt = pt + Len(td)
        ' // Copy the code
        CopyMemory Data(pt), Code(0), UBound(Code) + 1
        
        ' // Buffer is ready, inject it to cmd
        If WriteProcessMemory(pi.hProcess, lpDat, Data(0), ts, ret) Then
            If ret <> ts Then
                MsgBox "Error": CloseHandle pi.hThread: CloseHandle pi.hProcess
                VirtualFreeEx pi.hProcess, ByVal lpDat, 0, MEM_RELEASE
                Exit Sub
            End If
            ' // Launch the injected code
            thr = CreateRemoteThread(pi.hProcess, ByVal 0, 0, lpDat + pt, ByVal lpDat + otd, 0, 0)
            If thr = 0 Then
                MsgBox "Error": CloseHandle pi.hThread: CloseHandle pi.hProcess
                VirtualFreeEx pi.hProcess, ByVal lpDat, 0, MEM_RELEASE
                Exit Sub
            End If
        End If
        
        ' // Close handles
        CloseHandle thr
        CloseHandle pi.hThread
        CloseHandle pi.hProcess
        
    End Sub
    
    Private Sub CreateCode(Code() As Byte)
        ReDim Code(63)
        Code(0) = &H8B: Code(1) = &H74: Code(2) = &H24: Code(3) = &H4: Code(4) = &H31: Code(5) = &HDB: Code(6) = &H53: Code(7) = &H6A
        Code(8) = &HFF: Code(9) = &HFF: Code(10) = &H36: Code(11) = &HFF: Code(12) = &H56: Code(13) = &H14: Code(14) = &HFF: Code(15) = &H36
        Code(16) = &HFF: Code(17) = &H56: Code(18) = &H18: Code(19) = &H53: Code(20) = &HFF: Code(21) = &H76: Code(22) = &H4: Code(23) = &HFF
        Code(24) = &H56: Code(25) = &H1C: Code(26) = &H89: Code(27) = &H4: Code(28) = &H24: Code(29) = &H85: Code(30) = &HC0: Code(31) = &H74
        Code(32) = &H1B: Code(33) = &HFF: Code(34) = &H76: Code(35) = &H10: Code(36) = &HFF: Code(37) = &H76: Code(38) = &HC: Code(39) = &H53
        Code(40) = &HFF: Code(41) = &H76: Code(42) = &H8: Code(43) = &H6A: Code(44) = &HA: Code(45) = &HFF: Code(46) = &H74: Code(47) = &H24
        Code(48) = &H14: Code(49) = &HFF: Code(50) = &H56: Code(51) = &H20: Code(52) = &H53: Code(53) = &HFF: Code(54) = &H74: Code(55) = &H24
        Code(56) = &H4: Code(57) = &HFF: Code(58) = &H56: Code(59) = &H24: Code(60) = &H53: Code(61) = &HFF: Code(62) = &H56: Code(63) = &H28
    End Sub
    
    Private Sub Form_Load()
        LoadFromEXE
    End Sub
    
    Private Sub Form_Unload(Cancel As Integer)
        StoreToExe
    End Sub
    
    '\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ This procedure is running in other process \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
    
    ' Similar code in VB6
    
    'Private Sub ThreadProc(dat As ThreadData)
    '    Dim hRes As Long
    '    ' Wait for the termination of the main process
    '    WaitForSingleObject dat.hParent, INFINITE
    '    ' Process has ended, close handle
    '    CloseHandle dat.hParent
    '    ' Get handle of the editing of the resource
    '    hRes = BeginUpdateResource(dat.lpFileName, False)
    '    If hRes Then
    '       ' Wirte the needed data to EXE
    '       UpdateResource hRes, RT_RCDATA, dat.lpRsrcName, 0, ByVal dat.lpData, dat.dwDataCount
    '       ' Ending of the updating
    '       EndUpdateResource hRes, False
    '    End if
    '      ' Done !!!
    '    ExitProcess 0
    'End Sub
    
    ' Assembly code (NASM)
    
    '[BITS 32]
    '; ThreadProc
    'mov esi,dword [esp+0x04]; ESI = &dat
    'xor ebx,ebx             ; Const 0&
    'push ebx                ; Dim hRes As Long
    'push 0xFFFFFFFF         ; INFINITE
    'push dword [esi+0x00]   ; dat.hParent
    'call [esi+0x14]         ; WaitForSingleObject dat.hParent, INFINITE
    'push dword [esi+0x00]   ; dat.hParent
    'call [esi+0x18]         ; CloseHandle dat.hParent
    'push ebx                ; False
    'push dword [esi+0x04]   ; dat.lpFileName
    'call [esi+0x1c]         ; BeginUpdateResource(dat.lpFileName, False)
    'mov [esp],eax           ; hRes = eax
    'test eax,eax            ; IF hRes=0
    'je ExtProc              ; GoTo ExtProc
    'push dword [esi+0x10]   ; dat.dwDataCount
    'push dword [esi+0x0c]   ; dat.lpData
    'push ebx                ; 0
    'push dword [esi+0x08]   ; dat.lpRsrcName
    'push 0x0000000a         ; RT_RCDATA
    'push dword [esp+0x14]   ; hRes
    'call [esi+0x20]         ; UpdateResource hRes, RT_RCDATA, dat.lpRsrcName, 0, ByVal dat.lpData, dat.dwDataCount
    'push ebx                ; False
    'push dword [esp+0x04]   ; hRes
    'call [esi+0x24]         ; EndUpdateResource hRes, False
    'ExtProc:
    'push ebx                ; 0
    'call [esi+0x28]         ; ExitProcess 0
    Attached Files Attached Files

  2. #2
    Member
    Join Date
    May 2013
    Posts
    47

    Re: [VB6] - Store data to EXE.

    GOOD ider.thanks .may be you have many good Projects

  3. #3
    PowerPoster
    Join Date
    Jan 2020
    Posts
    3,742

    Re: [VB6] - Store data to EXE.

    I don't know how to read the *.res file or edit by vb code or vb6 addin, Can you help me?

  4. #4

  5. #5
    PowerPoster
    Join Date
    Jan 2020
    Posts
    3,742

    Re: [VB6] - Store data to EXE.

    Quote Originally Posted by The trick View Post
    xiaoyao, you can use VB 6 Resource Editor standard Add-in.
    Name:  resedit.png
Views: 1757
Size:  13.2 KB
    where is the code sources about resource edit tool?

  6. #6
    Fanatic Member Black_Storm's Avatar
    Join Date
    Sep 2007
    Location
    any where
    Posts
    575

    Re: [VB6] - Store data to EXE.

    is this tested on all windows like as xp 32bit or win 7 64 bit or win 10?
    i want use this code but how can protect that resource created itself or hide it inside exe,can i do that?or maybe another way to can save my data and edit data inside exe without need resource?

  7. #7
    Lively Member
    Join Date
    Sep 2016
    Posts
    94

    Re: [VB6] - Store data to EXE.

    Hi The Trck
    Very interesting.
    A module or a class would be welcome

  8. #8

    Thread Starter
    PowerPoster
    Join Date
    Feb 2015
    Posts
    2,671

    Re: [VB6] - Store data to EXE.

    Quote Originally Posted by Black_Storm View Post
    is this tested on all windows like as xp 32bit or win 7 64 bit or win 10?
    i want use this code but how can protect that resource created itself or hide it inside exe,can i do that?or maybe another way to can save my data and edit data inside exe without need resource?
    The protection isn't related to storing here. You can encrypt your data and store it to resource in the simpliest case.

    Hi The Trck
    Very interesting.
    A module or a class would be welcome
    What do you mean?]

    BTW this is other way to store the data to EXE tail. https://github.com/thetrik/CEmbeddedFiles

  9. #9
    Fanatic Member Black_Storm's Avatar
    Join Date
    Sep 2007
    Location
    any where
    Posts
    575

    Re: [VB6] - Store data to EXE.

    my means of protect is how protect this resource added in exe "RCDATA" part,i dont want somebody can see it in resource editors i want protect that "RCDATA" part or hide that "RCDATA" tab
    .

    image link : https://postimg.cc/3WrYxDdg

    because everybody easy can find it or replace it with another resource in res editors.
    any way to can hide it ?

    and i cant use any packer or etc to protect this exe file because after protect by other softwares it cant work for save data intself.
    any way to can fix this problem?



    i see that github too but i have 2 questsion about it
    1- can i add or modify string data too because maybe i dont need add files jst i want add or edit string data?
    for example i want jst save a counter data to can make my exe limited for 5 times jst with saved that counter variable itself.

    2- how size support , can i add a 100 mb file inside it or more than 10 files with each 100 mb or longer? and how can play theme for example i want add 4 mp4 videos but i want play theme inside exe too.
    Last edited by Black_Storm; Feb 15th, 2022 at 11:22 PM.

  10. #10

    Thread Starter
    PowerPoster
    Join Date
    Feb 2015
    Posts
    2,671

    Re: [VB6] - Store data to EXE.

    Anyone can replace the data anywhere. Just encrypt it and make checking by a checksum. There is no difference if you place the data in resources or inside an executable.

    1- can i add or modify string data too because maybe i dont need add files jst i want add or edit string data?
    for example i want jst save a counter data to can make my exe limited for 5 times jst with saved that counter variable itself.
    There is no difference a file or a string.

    how size support , can i add a 100 mb file inside it or more than 10 files with each 100 mb or longer? and how can play theme for example i want add 4 mp4 videos but i want play theme inside exe too.
    The size doesn't matter. If you plan to store big files inside an EXE it's better to use the second approach (append to tail) because no VM is used for this when the executable is loaded.

  11. #11
    Fanatic Member Black_Storm's Avatar
    Join Date
    Sep 2007
    Location
    any where
    Posts
    575

    Re: [VB6] - Store data to EXE.

    so its not safe for protect that rcdata and the only way for protect is checksum?!!! if yes which check sum vb project is better and worked on win xp till win 10?can send a best source code for check sum to can run in xp till win 10?

    if i dont want use like as this thread and using resource but if i want save inside exe so CEmbeddedFiles class is better?!! i seen before but CEmbeddedFiles saved files in .text section? because i did not find resource part in final exe when i use CEmbeddedFiles project.

    my english is weak but ur means of append to tail is same append to the file or appened to resource?
    can i use jst CEmbeddedFiles for what i want is that support (append to tail)?
    i ask this question in my other thread too how can save string and edit or delete it inside exe when i want use CEmbeddedFiles without need add files on disk
    Last edited by Black_Storm; Feb 17th, 2022 at 10:23 PM.

  12. #12

    Thread Starter
    PowerPoster
    Join Date
    Feb 2015
    Posts
    2,671

    Re: [VB6] - Store data to EXE.

    I think you can't use resources and EOF in the same exe. If you need to change some data in exe (like a counter or a small string) you just need to update it directly in the file (using a shellcode or an external executable). I think you can't write a shellcode so you can create a small executable which patches the main exe. Put it to main exe resources/section. Before finish your application extract this small executable to a file and run it with specified command line. This executable waits for the main executable has ended and patches the data.

  13. #13
    Fanatic Member Black_Storm's Avatar
    Join Date
    Sep 2007
    Location
    any where
    Posts
    575

    Re: [VB6] - Store data to EXE.

    Quote Originally Posted by The trick View Post
    I think you can't use resources and EOF in the same exe. If you need to change some data in exe (like a counter or a small string) you just need to update it directly in the file (using a shellcode or an external executable). I think you can't write a shellcode so you can create a small executable which patches the main exe. Put it to main exe resources/section. Before finish your application extract this small executable to a file and run it with specified command line. This executable waits for the main executable has ended and patches the data.
    i said this too here in linked thread so am i on correct way ?
    maybe need another modifer exe but created with vb and can access to resources in opened exe and edited and saved with replace to opened exe?
    if yes any sample code to can modify another exe vb and access to resource part and edit it?!!
    thread link : Re: any simple code for create ,add or edit or delete from resouce in runtime?

    my new thread about all we talked till now :
    add/delete/edit strings or files at runtime inside exe without res/section and show ?

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