Saving data from a program's export script to a file?

Discussions Related to Game Hacking and Memory Hacking Software

Moderators: g3nuin3, SpeedWing, WhiteHat, mezzo

Saving data from a program's export script to a file?

Postby bobbysoon » Mon May 18, 2009 1:33 pm

I'd like to make a better replacement for "GrabListener", a tool made for Discreet's gMax, which saves text in it's console window to a text based file. gMax is limited to the wrong kind of export format for CE developers, so it's a pain.
This is for Halo Custom Edition developers who can't afford 3ds max.
High poly exports like non-simple quality maps take too long, in my opinion, considering the many exports during the debug process.
I've found the lengthy part to be when the export script is streaming newline characters to gmax's listener window. It can take hours to export more than a simple map. Preparing the data for export takes a couple minutes, and exporting with 3ds takes a bit more, but this streaming to listener process is ridiculous. A cumbersome workaround is to export most newline characters as something else, and use a text search/replace program to convert them back to newline chars after the window's text is "grabbed" and saved, but it'd be nice if it just exported, and a side app just saved it. Potential high-end developers would still be encouraged to purchase the full app without this no-exporting bs, as gMax is otherwise limited in features, most notably rendering.
I imagine it's possible to have the external program (GrabListener2 maybe) get it's data from a global variable holding an array or structure, rather than the console window, but this must be complicated, acquiring content of dynamically allocated data from a variable found in a stack or heap or whatever the case is.
I see a variable's name can be found, and a couple addresses point to it. It's value must not be far away, as well as it's position in a heap. I image it'd need to start at the heap root or some such, to export in a timely fashion.
I need to reorganize the script so the data it collects is in a struct, but maybe we can figure some stuff out in the meantime.
Guidance, guesses, and/or suggestions would be greatly appreciated.
User avatar
bobbysoon
I Have A Few Questions
 
Posts: 2
Joined: Mon May 18, 2009 1:10 am

Postby L. Spiro » Tue May 19, 2009 6:20 am

Based on my understanding of your description:

If the stream of text is actually stored as a copy inside the program then you can find it easily simply by pausing the process while it is printing (research Hotkeys) and doing string searches.
If the text is being stored as one long chunk of text then you can rip it from memory all at once in one pass, using a breakpoint to tell you when the whole string has been composed.

The more likely situation is that the string is simply streamed out piece-by-piece.
Finding the pieces in memory is done the same way, except that you have to scan for the most recent few characters that were output to the window. in other words, the last whole line, or the last 5 characters.


You can also hook sprintf(), which is very likely the function they use to create the string parts.


L. Spiro
Our songs remind you of songs you’ve never heard.
User avatar
L. Spiro
L. Spiro
 
Posts: 3129
Joined: Mon Jul 17, 2006 10:14 pm
Location: Tokyo, Japan

Postby bobbysoon » Tue May 19, 2009 11:53 am

Sorry, my post was a bad essay on the task at hand

It's a struct of variables and arrays of structs created in the program's 'maxscript' environment that I'd like the new app to grab and write to file, without using gMax's listener window.
I'm not finished with the rewrite of the program's export script, but the main struct, and overall structure of the JMS file to be made is this:
Code: Select all
struct jmsExport
(
   checksum,
   jmsNodesCount,         --array size
   jmsNodesArray,         --array of structs
   jmsMaterialsCount,      --array size
   jmsMaterialsArray,      --array of structs
   jmsMarkersCount,      --array size
   jmsMarkersArray,      --array of structs
   jmsRegionsCount,      --array size
   jmsRegionsArray,      --array of structs
   jmsVertsCount,         --array size
   jmsVertsArray,         --array of structs
   jmsFacesCount,         --array size
   jmsFacesArray,         --array of structs
)

I'd like to pinpoint where the maxscript data is handled, and find the instance of struct jmsExport from there, if possible, if that's a valid assumption of maxscript's data handling. I imagine it would export quickly this way.
Furthermore, I have no idea how I'd begin making an app that digs it's fns into another app. Will I need WinAPI and Visual C++, or would Turbo C++ 3.0 (dos mode) be enough? Does MHS create apps, and would an app that lightly monitors untill a trigger value is detected, and then writes the data needed to a file, perhaps named by another tapped variable?

I should make an array of strings, shouldn't I?

i found a "maxscript.dll" in gmax's program folder. What can I do with this I wonder...
User avatar
bobbysoon
I Have A Few Questions
 
Posts: 2
Joined: Mon May 18, 2009 1:10 am

Postby L. Spiro » Tue May 19, 2009 4:11 pm

You said the listener prints formatted text to a console window, the same as what is later stored in a file.

If you want to work with the actual internal data structures you will have more work to do since you will have to format the data yourself.

But it will be faster as long as all the data is in memory at once.
Finding the data is simple as long as you know how it appears in memory. This is where you create a Script Search. Review the Final Fantasy VII® Script Search.
Your script simply scans for the structure based off what it must know about it. Once you find it (and can easily find it again later) you can begin tracking down the pointers to it via the normal searching methods (which are covered in so many places on this site it would be a sin to explain them here).

Once you create a Complex Address to the data of interest you can make a script to begin your export. L. Spiro Script has full file functionality and will allow you to do the full export as you please.


No MHS does not create stand-along executables. You can make the entire exporter with L. Spiro Script, however.


If you want to make a stand-alone application (and I know you do), you will have a lot of work to do. You still have to make it in L. Spiro Script just to test if it works. Then you have to move over to C or C++ and create a shell to replicate the MHS functionality of invading the target process and following a Complex Address.
You will need Win32 for it.

Waiting for a signal is never reliable on timers. You would usually need a breakpoint or code injection for best results. If you make your own application, however you will be stuck using timers or looping threads.


maxscript.dll probably has a lot of useful features in it. You should probably attach MHS to a process that loads/uses that DLL so you can see what functions it exports and how they are called.
There easily may be a function that does the whole export for you without printing to a console.


L. Spiro
Our songs remind you of songs you’ve never heard.
User avatar
L. Spiro
L. Spiro
 
Posts: 3129
Joined: Mon Jul 17, 2006 10:14 pm
Location: Tokyo, Japan


Return to General Related Discussions

Who is online

Users browsing this forum: No registered users and 0 guests