dadreamer Posted June 11, 2020 Report Share Posted June 11, 2020 (edited) I have updated this message, as after trial-and-error takes I've got success finally! As you can see, the VI is in runnable state and behaves without any errors. My steps to reproduce: 1. Unpacked lvlibp with 7-Zip unarchiver (as I'm on Windows currently) and pulled out "2" file (LIBPLBVW resource). 2. Extracted the inner resource blocks with readRSRC.py -x -i "2" command, got 2.xml, 2_DATA0.bin to 2_DATA4.bin and 2_LVzp.bin files. 3. Unpacked 2_LVzp.bin with an unarchiver, got NI_Embedded_Library.xml and Untitled 1.vi files. 4. Extracted the inner resource blocks from Untitled 1.vi with readRSRC.py -x -i "Untitled 1.vi" command, got Untitled 1.xml and a bunch of various resource sections. 5. Renamed 2_DATA0.bin (from step 2) as Untitled 1_VCTP.bin and placed it near Untitled 1.xml. 6. Added the following text to the end of Untitled 1.xml (before the last </RSRC> tag): <VCTP> <!-- VI Consolidated Types --> <Section Index="0" Format="bin" File="Untitled 1_VCTP.bin" /> </VCTP> 7. Packed the .xml and all the resources into a single VI with readRSRC.py -c -m "Untitled 1.xml" command, got Untitled 1.vi. 8. Extracted the inner resource blocks from Untitled 1.vi (again!) with readRSRC.py -x -i "Untitled 1.vi" command, got Untitled 1.xml and a bunch of various resource sections (is done to get VCTP processed correctly). 9. Opened Untitled 1.xml and removed everything from <LIBN> to </LIBN> (including the tags as well) changed the library name extension from .lvlibp to .lvlib (between <LIBN></LIBN> tags). To wit, this line <Library>Untitled Library 1.lvlibp</Library> should be turned into this <Library>Untitled Library 1.lvlib</Library> 10. Packed the .xml and all the resources into a single VI with readRSRC.py -c -m "Untitled 1.xml" command, got Untitled 1.vi. 11. Renamed NI_Embedded_Library.xml (from step 3) to Untitled Library 1.lvlib. 12. Opened Untitled Library 1.lvlib in a text editor and altered the lib URL to point to the new location. To wit, this line <Item Name="Untitled 1.vi" Type="VI" URL="Untitled 1.vi"/> should be turned into this <Item Name="Untitled 1.vi" Type="VI" URL="../Untitled 1.vi"/> 13. Opened the VI (LabVIEW did the library reload from the new path and reported), opened .lvlib. 14. In Project Explorer untied the VI from the library w/ RMB -> Remove from Library menu option, saved the both files w/ File -> Save option. Now the VI runs fine, so it might be a time to simplify this tutorial a little 🙃 If your tools could support lack of VCTP and recreate it automagically, that would be great for sure. Edited June 11, 2020 by dadreamer new information 1 Quote Link to comment
Mefistotelis Posted June 11, 2020 Author Report Share Posted June 11, 2020 8 hours ago, dadreamer said: If your tools could support lack of VCTP and recreate it automagically, that would be great for sure. My intent for 'readRSRC' is to have only two functions: - Extracting RSRC, without changes, with as little raw binary data as possible - Re-creating RSRC from extracted data, creating file identical to the one before extraction So any modifications to the file would have to be in a separate script. Like the one I made for recovering Front Panel - 'modRSRC' (I will probably rename it to fixRSRC at some point). Â But readRSRC should convert the DATA0 section to XML - that I might do at some point (assuming I will continue to support it long enough). Â Quote Link to comment
dadreamer Posted June 14, 2020 Report Share Posted June 14, 2020 (edited) So far I have left those instructions as they are, because I don't know atm, how to eliminate some steps. I believe, there should be a LabVIEW-native way to unlink the VI from the library, thus we could exclude steps 11-14. It would be easier then to automate this algorithm to process multiple VIs. Unfortunately Disconnect From Library method doesn't work on locked libraries and Open VI Reference or even Open.VI Without Refees don't work on broken VIs. There are Linker.Read Info From File and Linker.Write Info To File private nodes also, but I still have not figure out, whether they could be used for the task (any ideas?). That's why I decided to switch to LEIF formatted lib's and exe's. I found that we can bypass LEIF loader RE-ing using Save.To Buffer private node (always felt uncomfortable studying that loader, because it's rather complex). The node returns convenient RSRC with LVINLBVW block instead of LEIF, so we can easily save that into the file to deal later. I suppose, LEIF data is always translated into common resources by LabVIEW and they're in memory until the VI's are unloaded. Here's how a single VI may be extracted out of .lvlibp: extract_lvlibp_vi.vi And here's how the same may be done with the EXE: extract_exe_vi.vi To open VI inside EXE I used technique, described in this article: Passing Data Between LabVIEW Executable Reference VI and a VI Upd: see next message for the instructions. On 6/12/2020 at 1:08 AM, Mefistotelis said: assuming I will continue to support it long enough I appreciate if you find time to take a look at LEIF binaries some day, as I think you're more experienced in VI contents and internals than me. 🙂 By the way I tried readRSRC.py with LabVIEW 2020 built executable without FFF option and it worked like a charm. I can't do the same with PPL's, because that Fast File Format is forced onto them hardly and I've found no way to switch it off. Edited June 15, 2020 by dadreamer update Quote Link to comment
dadreamer Posted June 15, 2020 Report Share Posted June 15, 2020 (edited) Okay, now that is simplified. To extract VIs out of .lvlibp (no matter, if FFF-enabled or not): Open extract_lvlibp_vis.vi (attached -> extract_lvlibp_vis.vi ), set path to your PPL (.lvlibp) and the destination folder and run the VI. The files should be extracted and placed to the chosen folder. Extract the inner resource blocks from a single VI with readRSRC.py -x -i "YourVI.vi" command. YourVI.xml and a bunch of various resource sections should appear. Open YourVI.xml and change the library name extension from .lvlibp to .lvlib (between <LIBN></LIBN> tags). Remember the .lvlib name. Save and close the .xml. Pack the .xml and all the resources into a single VI with readRSRC.py -c -m "YourVI.xml" command. You should get YourVI.vi recreated. Do not open it yet. In LabVIEW create new empty library and save it into the same folder, where YourVI.vi resides. Use that name, you obtained on the step 3. Now drag YourVI.vi from the folder into the library's root. LabVIEW should reload the VI from the new path and report. * Untie YourVI.vi from the library w/ RMB -> Remove from Library menu option, save both files w/ File -> Save option. Now you may close YourVI.vi and open again to make sure, it's not broken. Optionally repeat the steps 2-7 for any other VIs from that .lvlib. To extract VIs out of .exe (for non-FFF EXE's you finish on the 4th step): Open YourApp.ini and add two lines to its end according to this article. Launch YourApp.exe and leave it in this state. Open extract_exe_vis.vi (attached -> extract_exe_vis.vi ), set path to the destination folder and run the VI. The files should be extracted and placed to the chosen folder. Make sure, you're using the same port number, that you've set on the step 1. If 3364 doesn't work for some reason, try another number (3363 etc.). For EXE's without FFF option: Now you may open your VIs and make sure, they are fine. For EXE's with FFF: go to step 5. Load a single VI into flarn's Resource Editor. ("Load" button). Find CLIv resource section and change its Type to LIvi. Find CLId resource section and change its Type to LIds. Save the VI with "Save" button. Don't do any other actions here like fixing checksums or whatever. Now you may open YourVI.vi to make sure, it's not broken. Optionally repeat the steps 5-8 for any other VIs from that .exe. * N.B.: In projects with more or less complex hierarchies it might be a good idea not to untie your VIs from the library, because it's very easy to mess with the correct order of such an unlinking. When done incorrectly, your VIs could become broken and to fix them you have to recreate the original VI(s) from the .lvlibp. Also to note, such an untying doesn't work neatly for VIs of different levels of dependence, i.e., a VI has some SubVI(s) and they all are contained into that .lvlibp; on unlinking them you'll likely get those SubVI(s) fine and the main VI broken. But if you really want to detach each and every VI from the library, you first make sure, that your VI is working fine inside that library, then unpack the VI with readRSRC.py, in .xml remove lines like <String>Untitled Library 1.lvlib</String> in LIvi and LIds sections, then pack again to VI, move dependent SubVI(s) out of the library and open up the main VI. It may work or may not, you test it out by yourself. Edited June 17, 2020 by dadreamer add some remarks Quote Link to comment
pawhan11 Posted July 3, 2020 Report Share Posted July 3, 2020 @Mefistotelis did You by any chance see how paths to dependencies are stored inside exe/packed libraries? Now I have to move entire hierarchy of PPLs to make this work. What is interesting if dependent PPL is stored on another drive it uses absolute path instead of relative... Quote Link to comment
Rolf Kalbermatter Posted July 3, 2020 Report Share Posted July 3, 2020 (edited) 1 hour ago, pawhan11 said: @Mefistotelis did You by any chance see how paths to dependencies are stored inside exe/packed libraries? Now I have to move entire hierarchy of PPLs to make this work. What is interesting if dependent PPL is stored on another drive it uses absolute path instead of relative... That's the standard procedure for path storing in LabVIEW. If the path root is different, LabVIEW will normally store the abolute path, otherewise a relative path relative to the entity that contains the path. Using relative paths is preferable for most things, but can have issues when you try to move files around outside of LabVIEW (or after you compiled everything into an exe and/or ppl). But absolute paths are not a good solution either for this. LabVIEW also knows so called symbolic path roots. That are paths starting with a special keyword such as <vilib>, <instrlib>, and similar. This is a sort of relative path to whatever the respective path is configured in the actual LabVIEW instance. They refer by default to the local vi.lib, inst.lib and so on directories but can be reconfigured in the LabVIEOW options (but really shouldn't unless you know exactly what you are doing). Chances to mess up your projects this way are pretty high. Edited July 3, 2020 by Rolf Kalbermatter Quote Link to comment
Mefistotelis Posted July 3, 2020 Author Report Share Posted July 3, 2020 Â Â 54 minutes ago, pawhan11 said: id You by any chance see how paths to dependencies are stored inside exe/packed libraries? Yes. Extract your file, and paths will be in XML. "LVPath" is actually a class, which is instantiated for many things. So all paths basically have the same structure. I export it to XML as list of strings - this is how it is really stored. Elements in the list are either normal strings, or tags which LV replaces with value from current config. Example: <LIvi> <!-- LinkObj Refs for VI --> <Section Index="0" Format="inline"> <LVIN Unk1="NI_InternetTK_Common_VIs.lvlib:Close Calling VI's Windows.vi" Unk2=""> <!-- VI To Lib Object Ref --> <VILB LinkSaveFlag="2"> <LinkSaveQualName /> <LinkSavePathRef Ident="PTH0" TpVal="0"> <String><vilib></String> <String>addons</String> <String>internet</String> <String>NI_InternetTK_Common_VIs.lvlib</String> </LinkSavePathRef> </VILB> </LVIN> </Section> </LIvi> Â Quote Link to comment
pawhan11 Posted July 3, 2020 Report Share Posted July 3, 2020 Thx @Rolf Kalbermatter, is there any magic trick that will allow me to use absolute path instead of relative when they have common root? Or define list of paths where PPL will try to find dependencies? I can edith this in lvlroj file but after save it is replaced back to relative. If I place lvlibp in lvlib folder it will be resolved using tag? @Mefistotelis those special tags like <vilib> are somehow predefined in LV? Can I create my own custom tags that LV will understand? Or something like probing or assemblyresolve in c#? Problem i am trying to address is that i ve 2 applications and one has public.lvlibp interface that can be used by another one. To make this work app 2 must have relative path to public.lvlibp after build and deployment...  Quote Link to comment
Mefistotelis Posted July 3, 2020 Author Report Share Posted July 3, 2020 (edited) 10 minutes ago, pawhan11 said: those special tags like <vilib> are somehow predefined in LV? Yes. "<" and ">" are just symbols used to allow storage in XML; these are so-called HTML Entities. So this string really is "<vilib>". 10 minutes ago, pawhan11 said: Can I create my own custom tags that LV will understand? Or something like probing or assemblyresolve in c#? No idea. There are more tags which can be used, but I never cared for listing them, or checking whether they're all hard-coded. EDIT: Reading @Rolf Kalbermatter answer above, I see he already answered this.   Edited July 3, 2020 by Mefistotelis Quote Link to comment
Popular Post Mefistotelis Posted July 15, 2020 Author Popular Post Report Share Posted July 15, 2020 Â 2 1 Quote Link to comment
Antoine Chalons Posted July 15, 2020 Report Share Posted July 15, 2020 At the end of the video you don't go too much into details about the missing block diagrams, I also noticed that the icon of the subvi is missing - that's not very important - but I was wondering if the connector pane is available, which leads me to my next question : after recreating the VIs from the EXE, if you replace the subVI with a newly created one with the same connector pane, are you able to generate the EXE? Quote Link to comment
sam Posted July 15, 2020 Report Share Posted July 15, 2020 nice demo. Well done. I appreciate the works and your passion for your work. I know you are showing this as proof of concept and it is great work and progress so far.  It maybe helpful to think of these points below while you are doing your LabVIEW RE.  Simple subVIs with more connector pane wired. Dynamically called subVIs Classes/Objects more complex diagram functions. Loops,events,Qs,.Net Assemblies, etc.  Much more complex projects. example 5k-10k subVI. Projects with Realtime components. also bug fix: at 12:57. the numeric values show "1,1" instead of "1". Quote Link to comment
Mefistotelis Posted July 15, 2020 Author Report Share Posted July 15, 2020 Â Â 29 minutes ago, Antoine Chalons said: At the end of the video you don't go too much into details about the missing block diagrams Oh, going into that is definitely not for 15 minutes video. Recovering it completely and automatically, for every VI - would be a project for several months (considering this is my afternoon project). It's way easier to make partial recovery, requiring the user to finish. And just placing block diagram with the components we've already recovered for FP - is trivial. 36 minutes ago, Antoine Chalons said: I also noticed that the icon of the subvi is missing - that's not very important Yeah, noticed that as well.. the whole connectors pane is very easy to handle, I will likely fix that in the nearby future. 37 minutes ago, Antoine Chalons said: after recreating the VIs from the EXE, if you replace the subVI with a newly created one with the same connector pane, are you able to generate the EXE? Yes. That is probably the main use of that solution - recover the project without Block Diagrams, then re-create only VIs that need updating, and re-build everything. Â Quote Link to comment
Mefistotelis Posted July 15, 2020 Author Report Share Posted July 15, 2020 (edited) 14 minutes ago, sam said: I know you are showing this as proof of concept and it is great work and progress so far. Yes. What I didn't mention in the video is - ATM the tool only supports the specific components I put into project. I didn't even looked at other controls yet. And for various flavors of numeric/boolean controls - all we can figure out is whether that's a control or indicator, the specific visual representation of the switch is lost - recovered one always looks the same. Â 14 minutes ago, sam said: It maybe helpful to think of these points below while you are doing your LabVIEW RE. Thank you, will consider that. Complex projects are already supported - you just need `find` to list all extracted files, and do the 3 actions for each of them: extract to XML, recover FP, re-create VI. Â 14 minutes ago, sam said: also bug fix:Â at 12:57. the numeric values show "1,1" instead of "1". Default data type for that numeric control is Double. For this type, my tool sets an increment of 0,1. If it was Integer, the increase would be 1. The original value of that increment is lost with the removal of FP. Â Edited July 15, 2020 by Mefistotelis Quote Link to comment
Mefistotelis Posted July 17, 2020 Author Report Share Posted July 17, 2020 Made CPC2 re-creation - connector pane is now there, but LV seem to not want to display it without BD... While at it, also made a simple icon creation. Â Quote Link to comment
sagardoshi65@gmail.com Posted February 6, 2021 Report Share Posted February 6, 2021 On 7/15/2020 at 5:42 AM, Mefistotelis said: Â Hello, I tried executing above commands in Git Bash and found that for one the EXE, after executing "./readRSRC.py -vv -x -i 1.exe_10_2_0" command I am getting "1_LANG.bin" and "1_LEIF.bin" but it is not generating "1_LVzp.bin" Below is a log generated.... $ ./readRSRC.py -vv -x -i 1.exe_10_2_0 1.exe_10_2_0: Starting file parse for RSRC extraction 1.exe_10_2_0: Block 'FLAG' index 0 recognized 1.exe_10_2_0: Block b'FLAG' max data size set to 32 bytes 1.exe_10_2_0: Block b'LANG' max data size set to 24 bytes 1.exe_10_2_0: Block b'LEIF' max data size set to 10979932 bytes 1.exe_10_2_0: Writing block b'FLAG' 1.exe_10_2_0: Writing inline XML for block b'FLAG' section 1500 1.exe_10_2_0: Writing inline XML for block b'FLAG' section 1501 1.exe_10_2_0: Writing inline XML for block b'FLAG' section 1502 1.exe_10_2_0: Writing inline XML for block b'FLAG' section 1550 1.exe_10_2_0: Writing block b'LANG' 1.exe_10_2_0: Storing block b'LANG' section 0 binary in '1_LANG.bin' 1.exe_10_2_0: Writing block b'LEIF' 1.exe_10_2_0: Storing block b'LEIF' section 0 binary in '1_LEIF.bin' 1.xml: Writing binding XML Â Â Could you please help me to know if there any reason for not generating LVzp.bin file and how to solve this. Thank you. Quote Link to comment
Mefistotelis Posted February 6, 2021 Author Report Share Posted February 6, 2021 The compiled project is clearly in LEIF block. Quote Link to comment
dadreamer Posted February 6, 2021 Report Share Posted February 6, 2021 12 minutes ago, sagardoshi65@gmail.com said: and how to solve this. To extract the VIs out of LEIF section (produced by Fast File Format option) you may try my instruction above. Depending on the number of the VIs in your executable and their hierarchy it may be not that easy, but it's definitely doable at least. 1 Quote Link to comment
sagardoshi65@gmail.com Posted February 16, 2021 Report Share Posted February 16, 2021 (edited) On 2/6/2021 at 7:20 PM, dadreamer said: To extract the VIs out of LEIF section (produced by Fast File Format option) you may try my instruction above. Hi Dadreamer,  Thank you for your suggestion. I followed your instructions and found that "extract_exe_vis.vi" works fine with .VI and .CTRL extensions but my exe contains .xctl (Xcontrols) and some .lvclass and this vi is throwing errors while saving it. (Due to path problems) E.g. Tab.lvclass:Tab.ctl Tab.lvclass:GetSubPanelViRef.vi ADC_AcqView.lvlib:SaveData.vi:Instance:2 Analysis.lvlib:ADC_Debug_Gen.vi:Instance:1 PagesArea.xctl:RenderPageMoveData.ctl PagesArea.xctl:ForceRender.vi  could you please look into this and help me to resolve it? Thank you. Best Regards, Sagar Doshi. Edited February 16, 2021 by sagardoshi65@gmail.com Quote Link to comment
dadreamer Posted February 16, 2021 Report Share Posted February 16, 2021 3 hours ago, sagardoshi65@gmail.com said: this vi is throwing errors while saving it. (Due to path problems) You may easily overcome this with the following modification. But you also will need all .xctl and .lvclass' files (that are plain XML after all) from the exe, otherwise your linked VIs won't open properly. Sadly I don't know the way to pull out such files from a LEIF, because App.ExportedVIs property does not return them. I'm not saying now, that you have to recreate .xctl/.lvclass from a scratch, as they are actually stored inside the exe. But the way to extract them is yet to be found. Quote Link to comment
sagardoshi65@gmail.com Posted February 17, 2021 Report Share Posted February 17, 2021 15 hours ago, dadreamer said: You may easily overcome this with the following modification. Thank you Dadreamer, I appreciate your help. Now at least i can see all used vis, controls in the folder. But could not open them. I tried Loading a single VI into flarn's Resource Editor and changed CLIv resource section Type to LIvi. and CLId resource section Type to LIds. But still could not open the VI. I am getting below error.   Quote Link to comment
dadreamer Posted February 18, 2021 Report Share Posted February 18, 2021 It's difficult for me to figure out the reasons behind your situation as I don't have your application and cannot do some tests with it. To me it looks like you don't have all the necessary dependencies extracted, thus LabVIEW fails to open the VI (assuming that you've done every step from the instruction properly). Are you receiving the same message when placing that VI onto the BD of a brand new VI? Well, I spent some time searching for ways to extract project library files (.lvlib, .xctl, .lvclass) and seems I found one. You might try to complete your file list by doing the following steps. 1. Install Full Featured Run-Time Engine (FF RTE) for your LabVIEW. You may find this package in your installation ISO, e.g. for LV 2019 it is ni-labview-2019-ff-runtime-engine-x86_19.* package from pool folder of LV19 image. 2. Go to C:\Program Files (x86)\National Instruments\Shared\LabVIEW Run-Time\2019 folder (for 32-bit LabVIEW 2019). If you have 64-bit LabVIEW, then you go to Program Files without (x86) ending. There you should have both lvrt.dll and lvffrt.dll. 3. Temporary rename lvrt.dll to some other name and make a copy of lvffrt.dll. Rename that copy to lvrt.dll. Now LabVIEW will start FF RTE when running executables instead of a common RTE. 4. Open your exe and put it into a stopped state (Run button should not be pressed). 5. Now you need to craft a dummy .xctl/.lvclass with the same name, that's assigned to the .xctl/.lvclass, you want to extract. That .xctl/.lvclass should already be loaded into the app's memory. As soon as it's crafted, open it in the same app with File -> Open menu entry. You should receive the following window along with some message. 6. Now you may save the project library with File -> Save Project menu entry. RTE will say, that it's unable to save inside the executable and offer you a browse dialog to choose the path to save. 7. Place that .xctl/.lvclass near other VIs (Data.ctl, Facade.vi etc.) and try to open it in a common LabVIEW. On opening it should relink all the files, then you save everything. 8. As a bonus you may try to save the main VI or some subVIs, it uses (File -> Save and View -> VI Hierarchy / Browse Relationships entries). But be prepared for RTE to crash suddenly, because it does not always go firmly. For me it did not want to save XControl files at all. Â Maybe this hack will work for you or you will find a working combination of few techniques... There are not so many LV users, who ever thought of tearing down the exe's, not even saying about bringing the resulting files to a workable state. Quote Link to comment
HardWorker Posted April 4, 2023 Report Share Posted April 4, 2023 Has anybody succesfully reversed a exe. i have a simple Labview program that someone long before me wrote and i would like to modify it. I can send you the file to play with if you would like. Thanks Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.