Jump to content

Mefistotelis

Members
  • Content Count

    24
  • Joined

  • Last visited

Community Reputation

0

About Mefistotelis

  • Rank
    Active

LabVIEW Information

  • Version
    LabVIEW 7.0
  • Since
    1986

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. I don't think I can be completely convinced to your point: I agree refactoring LV doesn't make sense now, but I think something should've been done years ago to allow the support. Even if no conversion was done at a time, as soon as multi-lingual versions of Windows and Mac OS started popping out, it was obvious the conversion will be an issue. I'm not talking there should be a conversion right away, just that even then, it was obvious that storing just the information which code page is in use, would be a prudent choice. Now for really implementing the conversion: It wouldn't be needed for the OS to support anything - `libconv` can be compiled even in Watcom C (I'm not stating libconv should have been used, only stating that doing codepage conversion even in DOS was not an issue). Around 1994, I wrote a simple code page conversion routine myself, in Turbo Pascal. Not for unicode, it converted directly between a few code pages, with a few simple translation tables. It also had a function to convert to pure ASCII - replace every national character with the closest english symbol (or group of symbols). That would be good enough support for pre-unicode OSes - it wasn't really necessary to support all unicode characters, only to allow portability between platforms which LabVIEW supported. Finally, I don't think LabVIEW uses native controls (buttons etc.) from the OS - it treats the native window as a canvas, and draws its own controls. So support on of multi-lingual text in controls is not bound to the OS in any way. For implementation details within LabVIEW: That would be more tricky, and I understand possible issues with that. LabVIEW operates on binary data from various sources, and if the VI tells it to print a string, it doesn't keep track whether that string came from the VI and has known code page, or come from a serial port with a device talking in different encoding. There are still ways to solve such issues, just not completely transparent for the user. Plus, most string used in user interface are not really changing at runtime. I didn't actually knew that LabVIEW is considered "classic" version and is being replaced by NXG. That is strong argument against any refactoring of the old code. The conversion I introduced to my extractor works well, so this shouldn't be much of an issue for me.
  2. Great overview, thank you. What LabVIEW could have done is just storing the information about code page used for the VI. That would then allow conversion when the sting is displayed on screen, if necessary. But since there's no info on codepage within the VI, I implemented it as a parameter (the tool I made exports VI to XML and within the XML the encoding is UTF-8) : https://github.com/mefistotelis/pylabview/blob/master/README.md#text-code-pages I think if you don't live in western country, you might have different view on that. Even if the 90% statistics is true (it sounds iffy to me, but I have no data to subvert it), people from other countries probably mostly see VIs created near them. I've seen a lot of VIs with asian language, probably Chinese. I can't even read the alphabet, so can't tell for sure which code page is there. Sometimes when there's longer description, I can just check with Google translate; but there are often 1-2 words only, ie. in names of interfaces. The translator then either gives something plausible for many code pages, or non-technical term for all of them. When I get connector name and see "stick noodles" for Chinese translation (w/ their code page), and "fluffy neckcloth" for Japanese (w/ their code page), I still can't tell the origin of that file. Nor what the connector does. (I never got these specific words, but what I got wasn't very far). Anyway, there's a lot of people in China. And a lot of factories, which do semi-automated Quality Assurance. Such tasks might be often handled with help of LabVIEW.
  3. On LabView 2014, I see that my VI files happily store strings using current OS (testing on Windows) code page. I assume there's no conversion mechanism, and if I use the VI on another OS, or just different language Windows, I will get unreadable mish-mash instead of the proper text? Is that fixed in LV 2019, or do NI still avoid UTF? I realize this is not an issue, or at least minimal issue, when you describe things in english and avoid using ascii codes > 127. (though note that even original LV libraries contain OS-specific char codes, mostly a special variants of apostrophe and minus/pause: ` and -. I though the world has finished moving to unicode more than 15 years ago... EDIT: Verified on Windows with different language. I do get invalid characters. There is no conversion, LabView just tries to print the characters using current Windows code page, resulting in garbage. How this is still an issue today? I need to provide the ability to set code page as input parameter to my VI reader. EDIT2: Now i know everything I need - see "Character Code Issues" chapter: http://zone.ni.com/reference/en-XX/help/372614J-01/lvconcepts/porting_among_platforms/ It's funny how lack of proper string conversion is called "compatibility feature". Reading the chapter gives you a feeling that LabView supports the conversion whenever possible, but it doesn't seem to be the reality.
  4. Nope. that's not what I found. You're right with ButtonsHidden field being an integer which bits correspond to something (I assume visibility of some buttons), but sr_field22 turned out to be something else - the type of VI. This type is actually part of LV documentation: https://zone.ni.com/reference/en-XX/help/371361R-01/lvprop/vi_vi_typ/ I already did proper renaming in my code. There seem to be many properties which I could find in code based on the documentation (click "VI Properties" in the link above to see them). Below, they are listed with "property ID" of each - will check whether this can provide me with some more field names: https://labviewwiki.org/wiki/VI_class
  5. A good example I just found: void InitButtonsHidden(INSTRUMENT **a1) { (*a1)->sr_field14 = gButtonsHidden[(*a1)->sr_field22]; } Now we can rename one field to 'buttonsHidden', and can assume another field contains enum value representing either state or type.
  6. You are completely right with the assessment of what this function does. But I can't agree it is unexciting: - It provides us with full information on how to divide the LVSR block into single values, and it even names one of the values. - It gives us offsets within INSTRUMENT where each value is stored, so that we can cross-reference it with other functions and check what they do (as you see, I already named the items within INSTRUMENT to "sr_field*" so that I can easily search ehere each of these is used further. So actually, almost everything about LVSR which is in my code, comes from this single function: https://github.com/mefistotelis/pylabview/blob/master/LVblock.py#L100 Thanks! I actually downloaded that whole FTP already; and yes, this is where I got LV3.1.1 from. There are 2 binaries - Win16 and WinNT; the WinNT one is better for analysis. But, as I previously stated - before LV6.0, the blocks within VI files were a bit different - so I prefer to work on more recent code. As an example, in LV5.0 there was LVIN block instead of the LVSR discussed above.
  7. I got a 3.5 inch floppy drive with USB interface - they were very cheap at some pint. Anyway, I browsed through various releases available in obscure places of the web. There's A LOT of things created by NI which either use the standard LV runtime environment, or use parts of the LV code. I downloaded > 100GB of various files when I decided it's time to stop. There was probably way more to find, but I have to limit my time. Findings: - Files from Windows platform are the worst port to reverse engineer, mostly because Windows libraries (.DLL) define exported routines explicitly. - UNIX base releases (solaris,linux) are the best to debug - compiled for popular CPU architectures, and shared libs (.SO) have all routines exported - meaning their names are retained - For some obscure platforms, I found static libraries (.a/.lib) files included in the release. These have the most info on source code retained, but not the whole code was in that form. Not the part I need anyway. - The best version to focus on seem to be LV6.0 - the code is a lot less bloated than in newer releases, and the core of the tool didn't seem to have changed much since that release (though I didn't found much LV5.0 releases - I can tell 4.0 is too old and does not have many blocks which exist in modern VI files, for 5.0 - I'm not sure) Here's the loading of LVSR block in LabView 6.0. Unfortunately, I still don't have struct definitions. But at least I know how the structs are named, thanks to C++ name mangling. void RToVI(SAVERECORD **sr, INSTRUMENT **instr) { char fld10a; char fld10b; INSTRUMENT *dInstr; int state; (*instr)->sr_field4 = (((*sr)->field_4 & 0xFF0000) >> 8) | ((unsigned int)(*sr)->field_4 >> 24) | (((*sr)->field_4 & 0xFF00) << 8) | ((*sr)->field_4 << 24); (*instr)->sr_field8 = (((*sr)->field_8 & 0xFF0000) >> 8) | ((unsigned int)(*sr)->field_8 >> 24) | (((*sr)->field_8 & 0xFF00) << 8) | ((*sr)->field_8 << 24); (*instr)->sr_fieldC = (((*sr)->field_C & 0xFF0000) >> 8) | ((unsigned int)(*sr)->field_C >> 24) | (((*sr)->field_C & 0xFF00) << 8) | ((*sr)->field_C << 24); (*instr)->sr_field12 = _byteswap_ushort((*sr)->field_12); (*instr)->instrState = (((*sr)->instrState & 0xFF0000) >> 8) | ((unsigned int)(*sr)->instrState >> 24) | (((*sr)->instrState & 0xFF00) << 8) | ((*sr)->instrState << 24); (*instr)->sr_field14 = _byteswap_ushort((*sr)->field_14); (*instr)->sr_field16 = _byteswap_ushort((*sr)->field_16); (*instr)->sr_field20 = _byteswap_ushort((*sr)->field_20); (*instr)->sr_field22 = _byteswap_ushort((*sr)->field_22); (*instr)->version = (((*sr)->version & 0xFF0000) >> 8) | ((unsigned int)(*sr)->version >> 24) | (((*sr)->version & 0xFF00) << 8) | ((*sr)->version << 24); (*instr)->sr_field24 = (((*sr)->field_24 & 0xFF0000) >> 8) | ((unsigned int)(*sr)->field_24 >> 24) | (((*sr)->field_24 & 0xFF00) << 8) | ((*sr)->field_24 << 24); (*instr)->sr_field1C = (((*sr)->field_1C & 0xFF0000) >> 8) | ((unsigned int)(*sr)->field_1C >> 24) | (((*sr)->field_1C & 0xFF00) << 8) | ((*sr)->field_1C << 24); qmemcpy(&(*instr)->sr_field34_md5, (*sr)->field34_md6, 0x10u); qmemcpy(&(*instr)->sr_field28, &(*sr)->field_28, 0xCu); RevBL(&(*instr)->sr_field28); RevBL(&(*instr)->field_2C); RevBL(&(*instr)->field_30); fld10a = (*sr)->field_10; fld10b = HIBYTE((*sr)->field_10); (*instr)->is_sr_field10_flag0200 = HIBYTE((*sr)->field_10) & 2; (*instr)->is_sr_field10_flag0100 = fld10b & 1; (*instr)->is_sr_field10_flag0400 = fld10b & 4; dInstr = *instr; if ( (*instr)->sr_field4 & 0x20000 ) { state = dInstr->instrState; if ( state & 0x200 ) { dInstr->instrState = state & 0xFFFFFDFF; DBPrintf("Fixing instrState, remove viDebugCapable from subroutine VI"); } } }
  8. How cute - NI is protecting some values stored in memory at runtime by XOR'ing them with seed which depends on the VMA. Here's what it does to an MD5 checksum stored at `ptr` (hence size=16), code comes from LV14: seed = ptr ^ 0xDEADCAFE; i = 0; do { *(uint8_t *)(i++ + ptr) ^= seed; seed >>= 1; } while ( i < 16 );
  9. Thanks for all the info! Searching for various NI things on the Internet, I found quite a lot of packages which included the LV RT. Various toolsets, drivers, and labview-based solutions. Though most of these use standard release of the RT installer. Unfortunately I have no pre-release versions. And this is where I expect higher chance of having some debug info left. I've seen indications that VI Logger 1.1 had a pre-release RT in it, but I could only find the fixed 1.1.1. As of now, I couldn't find the LV 2.5 as well. I found LV 6.0 on one of my old CDs, that's the oldest version I have.
  10. Labview exists for decades. It had thousands of releases. When was the last time NI left debug symbols by mistake? How to recognize a release with debug symbols left: - Nowadays Visual Studio keeps the symbols in a PDB file - so probably lvrt.pdb, but it might also have different name - depends on whether the DLL is renamed after build. - Previously, up to around year 2000, debug symbols were stored in the EXE/DLL - so lvrt.dll file size would be extraordinarily large, circa 2x-3x the normal size - Most compilers can also generate MAP file - it doesn't store as much as full debug symbols do, but has all global variables and functions named - which is still way more than nothing
  11. Thanks @Stinus Olsen, will look into some of these. The tool I made can now extract and re-create most VIs, like this: ./readRSRC.py -vvv -x -i './examples/empty_vifile_lv14f1.vi' ./readRSRC.py -vvv -c -m './empty_vifile_lv14f1.xml' cmp -l './examples/empty_vifile_lv14f1.vi' './empty_vifile_lv14f1.vi' Though there are still a few for which `cmp` shows difference between original file and re-created one (I've run it on the standard VIs from LV2014, on thousands of files only a few had differences). Also, it currently leaves all Blocks as BIN files - does not parse their content.
  12. Back to the salt - the algorithm seem to use some additional data to select which interface is used. It may be some kind of count. I executed my reader on all the VIs built into LabView 2014 Well not quite.. I was too lazy to extract VIs from LLBs. But it was still over 13000 files. Anyway, in large majority of cases the counts were taken from LAST interface. For less than 4% only zeros were used instead, and for less than 1% - the interface used was previous to last, not the last. There were also single cases where even earlier interface was used. If anyone would like to take a look, attached it the result of the following commands: find ./vi.lib -name '*.vi' -o -name '*.ctl' | sed 's/'"'"'/\\'"'"'/g' | xargs -I {} ./readRSRC.py -vvv -p -i '{}' 2>&1 | tee log_vi_lib.txt sed -n 's/^.*: \(Found matching salt .*\)$/\1/p' log_vi_lib.txt | sort | uniq -c Figuring out the specifics of interface selection would require deep dive into RE libraries, so I'll skip it for now. Now I want to make a function to export the data into some modificable form, and re-import again into proper VI. I will leave most data in binary form, only the parts I need will be fully parsed. Any comments / advice? lv14_builtin_vi_lib_all_salts.txt
  13. I see; so for the XML function, the tool requires LV2015+. This also means the tool doesn't do VI conversion, just uses functionality which is part of the LabView RE. I don't know much about LabView. For most of the tools I use, the default state is that they do 'work'. Didn't know I shouldn't expect that . There's also that: In general, I'm looking into this as I'm planning to implement VI-to-XML conversion by myself, and I think it would be nice to keep the conventions introduced by NI. EDIT: Oh, this was actually already discussed, just a few posts before. Should've read before posting, sorry.
  14. Any idea on what's up there? LabView 2014 Loading a VI for binary viewing works fine. Loading for XML viewing gives the following error. Tried several VIs, including very simple (empty) one.
  15. I implemented both interface counting and sequential check (called it brute-force). Will try to check whether there's a pattern in interface selection - I would prefer not to base that on guessing, as I'd like a tool which exports the VI to a set of XMLs and BINs, and then re-creates VI from scratch, using only the exported files. I could make the "salt interface index" a part of exported XMLs. But maybe the pattern is simple.
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.