Jump to content

Recommended Posts

Posted (edited)

Hey everyone, 

I’ve been working with a simple program that converts Darkspore game binary files (like .aiDefinition, .noun, .phase, .characterAnimation, .classAttributes, .markerSet, .nonPlayerClass, .npcAffix, .playerClass) into XML, but I'm running into some issues. The program seems to be built from a Visual Studio project (and likely and sent directly from the Release/Debug folder), and I’ve been trying to analyze it. I tried decompiling it using Ghidra and IDA, but I’m having trouble with the main function (FUN_140006470), which I can’t fully decompile or view in Graph.

The program takes arguments in the following way:

>Testing.exe command-line: path filetype [recursive]
	path: path to file or directory
	filetype: noun, characteranimation, etc...
	recursive: parse all files in path (with filetype as extension)
	xml: export parsed files as XML

For example, running this:
 

Testing.exe D:\DalkonParser\creatureeditor_el_anime_arm.Noun.bin noun xml

It doesn't do anything when I run it, and just prompts with "Press any key to continue..." instead of converting the files to XML. I’ve tried testing it on three different machines, but the result is the same.

I used Dependency Walker, and it seems to be searching for standard Visual Studio DLLs, which are all installed. I also noticed that the program calls a certain function, which might be related to the issue, but I'm unable to fully analyze it.

Here’s where I’m stuck:
- The program doesn’t do anything when it should convert the files, it just exits with the “Press any key to continue...” message.
- I’m not sure if there’s an error in my usage of arguments or if something’s wrong with the program itself.

I participate in the recap_server project (local server) for darkspore and the former developer dalkon wrote this script to convert these files, but he disappeared in 2022, so it is not possible to obtain the source code for this executable. In the recap source code (part also written by dalkon) it is possible to see a script that reads these files already parsed in xml:
https://github.com/vitor251093/recap_server/blob/main/darkspore_server/source/game/noun.h

Has anyone experienced something similar or have any suggestions on how I can figure out what’s causing this? Any advice on how to approach the debugging process would be greatly appreciated.

Thanks in advance! 
I love this community

file_examples.zip DalkonParser.7z xml_parsed_by_dalkon.zip

Edited by JeanxPereira
Posted
On 2/1/2025 at 3:53 PM, shak-otay said:

Hey, did you set a breakpoint on <open> and  then step through to see what the app does?

Testing-openFile.png

hey, thanks for the reply. in my execution the values are a little different, but even inserting the breakpoint on fopen I still couldn't detect the problem

Did you include any sample files in the execution arguments? like:
"D:\DalkonParser\Testing.exe" "D:\DalkonParser\creatureeditor_el_anime_arm.Noun.bin" noun xml

I don't understand much about these raw analyses, but I think the problem occurs after fopen (I'm not sure about that at all)

image.png

Posted
3 hours ago, JeanxPereira said:

hey, thanks for the reply. in my execution the values are a little different, but even inserting the breakpoint on fopen I still couldn't detect the problem

Did you include any sample files in the execution arguments? like:
"D:\DalkonParser\Testing.exe" "D:\DalkonParser\creatureeditor_el_anime_arm.Noun.bin" noun xml

I don't understand much about these raw analyses, but I think the problem occurs after fopen (I'm not sure about that at all)

image.png

I added some breakpoints in the file creation functions and the last one before the application is closed with "Press any key to continue. . . " is this one <CreateFileW>:

RAX : 00007FFD0E906E50     <kernel32.CreateFileW>
RBX : 0000000000000080
RCX : 000001E58D4CC470     L"D:\\DalkonParser\\creatureeditor_el_anime_arm.Noun.bin"
RDX : 0000000080000000
RBP : 0000000080000000
RSP : 000000CB46BDED08
RSI : 000001E58D4CC470     L"D:\\DalkonParser\\creatureeditor_el_anime_arm.Noun.bin"
RDI : 000000CB46BDF3F0
R8  : 0000000000000003
R9  : 000000CB46BDF238
R10 : 0000000000000035     '5'
R11 : 000001E58D4CC4DA
R12 : 0000000000000003
R13 : 0000000000000000
R14 : 0000000000000003
R15 : 000000CB46BDF238
RIP : 00007FFD0E906E50     <kernel32.CreateFileW>
RFLAGS : 0000000000000300     L'̀'
ZF : 0
OF : 0
CF : 0
PF : 0
SF : 0
TF : 1
AF : 0
DF : 0
IF : 1
LastError : 00000000 (ERROR_SUCCESS)
LastStatus : C0000135 (STATUS_DLL_NOT_FOUND)
GS : 002B
ES : 002B
CS : 0033
FS : 0053
DS : 002B
SS : 002B
DR0 : 0000000000000000
DR1 : 0000000000000000
DR2 : 0000000000000000
DR3 : 0000000000000000
DR6 : 0000000000000000
DR7 : 0000000000000000

DLL not found?
Could Dalkon have forgotten to send some dependencies created within the project itself?

  • Engineer
Posted (edited)

A missing DLL, I thought so. But the name is unknown. Maybe it's possible in IDA to find the SetLastError function (to set a BP on it). In xdbg I couldn't find it.

(GetLastError() is in ucrtbase.dll)

edit: ok, SetLastError() is there, too

I wasn't in the mood to step through ucrtbase, so did an "execute 'till return" which ended up in kernel32.dll. Haha.

And even if the knew the name of the missing dll, it's pointless, imho, as long as you can't get it.

Edited by shak-otay
Posted
31 minutes ago, shak-otay said:

A missing DLL, I thought so. But the name is unknown. Maybe it's possible in IDA to find the SetLastError function (to set a BP on it). In xdbg I couldn't find it.

(GetLastError() is in ucrtbase.dll)

edit: ok, SetLastError() is there, too

I wasn't in the mood to step through ucrtbase, so did an "execute 'till return" which ended up in kernel32.dll. Haha.

And even if the knew the name of the missing dll, it's pointless, imho, as long as you can't get it.

what a shame 😞
Do you think it would be possible to make the functions readable so that a new parser could be created? like the function FUN_140006470 which seems to be large and may contain information about how the structure of these files works

Posted (edited)
On 2/3/2025 at 5:47 PM, shak-otay said:

A missing DLL, I thought so. But the name is unknown. Maybe it's possible in IDA to find the SetLastError function (to set a BP on it). In xdbg I couldn't find it.

(GetLastError() is in ucrtbase.dll)

edit: ok, SetLastError() is there, too

I wasn't in the mood to step through ucrtbase, so did an "execute 'till return" which ended up in kernel32.dll. Haha.

And even if the knew the name of the missing dll, it's pointless, imho, as long as you can't get it.

I found this screenshot of the project:
he also made available a catalog xml file

unknown.thumb.png.e3596ec1be2b0547269e46a4d1223b71.png

unknown.thumb.png.f16b7a6af20e089aabe19722aba891ea.png

part of the recap code appears to contain the declarations presented in the Testing.exe code (such as CharacterAnimationType, NounType, CharacterAnimationType)
:
https://github.com/vitor251093/recap_server/blob/main/darkspore_server/source/game/noun.h

also looking at the Testing.exe log:
unknown.thumb.png.9ff4bf63733d4a373a6fce36419c9faa.png

catalog (2).7z

Edited by JeanxPereira
  • Engineer
Posted
1 hour ago, JeanxPereira said:

what a shame 😞
Do you think it would be possible to make the functions readable so that a new parser could be created? like the function FUN_140006470 which seems to be large and may contain information about how the structure of these files works

Is it worth the effort? Seems, it would be easier to create a "new parser" based on header files from the github project you linked to. (My personal opinion only, though.)

Plus, it's not clear what Testing.exe and catalog.xml were good for exactly.

(Might be worth a 2nd look if you could retrieve more information (or even sources) from web archives.)

  • Like 1
Posted (edited)
On 2/3/2025 at 7:41 PM, shak-otay said:

s it worth the effort? Seems, it would be easier to create a "new parser" based on header files from the github project you linked to. (My personal opinion only, though.)

Plus, it's not clear what Testing.exe and catalog.xml were good for exactly.

(Might be worth a 2nd look if you could retrieve more information (or even sources) from web archives.)

testing.exe was a parser that structured these files found inside one of the game's packages (.package files that can be extracted using SMFX (SporeModderFX), specifically in AssetData_Binary.package). These XML files were used in the Recap project (a local server) and contain information about the map, enemy positions, special effect placements within the game, objects, animations, and many other things.

The catalog file is also included in AssetData_Binary under the name catalog_131 with the same file structure. It appears to be a list that declares all the game's map assets so they can be read correctly by the server.

In our Discord channel, it is possible to find many old messages about Dalkon's development and progress, but unfortunately the source code for this application did not appear.

In summary, these files seem crucial for reconstructing the game's maps and levels.



 

I also believe the most viable solution would be to create a parser from scratch again, analyzing your old messages and also the Recap project's code, which seems to have some of the necessary parameters in valid XML.

recap_server/darkspore_server/source/game/noun.h

However, testing.exe seems to contain many more parameters and much more context about these files (graphical view in IDA of a large function  FUN_140006470 inside the application).

Captura de tela 2025-02-03 201933.png

Captura de tela 2025-02-03 202113.png

Captura de tela 2025-02-03 202425.png

Edited by JeanxPereira
  • Engineer
Posted
43 minutes ago, JeanxPereira said:

However, testing.exe seems to contain many more parameters and much more context about these files

How about "Ghidra"? I read you can use it to create source code from functions in binary data.

IDA should be capable of that, too. (But dunno for sure, never used it.)

Of course without debug info (pdb file?) you wouldn't get the original names of functions and variables, just something like fct_00000001, fct_00000002,

bool_var_0001, bool_var_0002, int_var_0001, int_var_0002 and so on.

Posted (edited)
On 2/3/2025 at 8:50 PM, shak-otay said:

How about "Ghidra"? I read you can use it to create source code from functions in binary data.

both were unable to decompile the FUN_140006470, Ghidra takes hours and simply closes xD

Edited by JeanxPereira
Posted

I'll try to create something simple for now, based on what he provided on discord as .noun and .level files already structured in .xml and try to get a similar result.
Thanks a lot for all the help and quick responses! You've given me a great direction to follow for the advancement of the Ressurection Capsule project. I will document the progress here 🙂

  • Engineer
Posted
6 hours ago, JeanxPereira said:

I'll try to create something simple for now, based on what he provided on discord as .noun and .level files already structured in .xml and try to get a similar result.

That's a good idea. Good luck!

Too sad that it has to be done nearly from scratch again although a solution existed already.

That's then a project depends on one person (more or less) who disappears without a trace.

  • Thanks 1
  • Engineer
Posted

From a first glance it looks as if there's more information in the hexbm than in the Noun file.

Plus I couldn't find any of these numbers in the noun, no matter which endianness used:

3005826508

3005861007

3016501703

1342177279

3016501619

1342141696

3005819340

3005840844

3016525353

  • Like 1
Posted (edited)
2 hours ago, shak-otay said:

From a first glance it looks as if there's more information in the hexbm than in the Noun file.

Plus I couldn't find any of these numbers in the noun, no matter which endianness used:

3005826508

3005861007

3016501703

1342177279

3016501619

1342141696

3005819340

3005840844

3016525353

the red markings I made were assumptions that they could be the addresses for the strings, based on the sequence generated by the parser log with this file (PC_EL_Rogue) and also in the XML. Do you think they are unrelated? Did the parser take the keys/strings sequentially and directly from where they are?

the keys apparently being parsed before what is shown in the file in hex on log:
image.png.776e3d1ea25eee2270d8ec5135c2139f.png

PC_EL_Rogue.Noun.xml.zip

Edited by JeanxPereira
  • Engineer
Posted (edited)

I have no idea. Seems I confused the hexbm with the xml file. What is the "parser log"? The hexbm"?

How is the parse_struct created?

I found the colors of the pattern editor always confusing, btw.

I prefer a raw hex access to files:

 

PC_El_Rogue Noun.png

Edited by shak-otay
  • Like 1
Posted (edited)
35 minutes ago, shak-otay said:

Seems I confused the hexbm with the xml file. What is the "parser log"? The hexbm"?

Sorry, that was a bit confusing

".hexbm" is the format used to store bookmarks in the imhex program (the program I'm using to view the files in hex) I used it to be able to note what each part is
"parser log" is the result generated by the parser created by dalkon (Testing.exe)
".xml" the xml file is also the result of the parser but structured in xml (which is what I intend to do to use on the local server)

Edited by JeanxPereira
  • Engineer
Posted (edited)
29 minutes ago, JeanxPereira said:

"parser log" is the result generated by the parser created by dalkon

Which "parser"? Testing.exe?

Ok, seems I totally missed your post as of Monday. So Testing creates a log? I wasn't aware of this.

Edited by shak-otay
Posted (edited)

  

10 minutes ago, shak-otay said:

So Testing creates a log? I wasn't aware of this.

yes, it creates this information, it's this one, this capture was sent by Dalkon via Discord and not by me :

On 2/3/2025 at 6:40 PM, JeanxPereira said:

desconhecido.polegar.png.9ff4bf63733d4a373a6fce36419c9faa.png

 

Edited by JeanxPereira
Posted (edited)

Regarding the Dalkon parser, a user on the server discussed it with a friend, who suggested that the issue is due to a missing DLL from a specific version of the C++ Runtime. To resolve this, I installed all available versions. However, I now get error 0x000007b, indicating that a required DLL is still missing. The problem is that many minor versions cannot be installed without conflicting with existing ones, making it impractical to install them individually. Is there any alternative solution for this?

I tried to install all available versions but they ended up conflicting because some were already installed:
https://github.com/abbodi1406/vcredist/blob/master/source_links/README.md

image.png.275e24d1c6063be2111a427bbbb957e5.pngsAefARWFE.thumb.png.2c1d3c792a155744d499f1c93c8c1fc3.pngimage.thumb.png.6622a940085d8769cea34d93e4bd5721.pngimage.png.36b8cd370c42d005305c83c3ca885006.pngScreenshot_20250206_114204_Discord.thumb.jpg.f24e61e890c0756c9337af9544be16ac.jpgimage.thumb.png.ac62383fc9499b4fc94bd2519626b456.png

Edited by JeanxPereira
  • Like 1
  • Engineer
Posted
46 minutes ago, JeanxPereira said:

 The problem is that many minor versions cannot be installed without conflicting with existing ones, making it impractical to install them individually. Is there any alternative solution for this?

Wouldn't a virtual machine do the trick? VirtualBox for example. Or Hyper-V (has to be activated in "Windows features", afaik)

Strange, that we don't get the name of the missing dll. (I had several dozens of missing dlls in the past years:classic_blink:, but their names were always displayed, afaicr.)

Posted (edited)
15 minutes ago, shak-otay said:

Wouldn't a virtual machine do the trick?

I tried to use a VM but it gave the same error (0x000007b) when installing all the packages of all the basic versions (those that are AIO installers (all in one)), unless I have to test version by version what are 384 installers and 5.15 GB, I think it's unfeasible xD

I thought about finding the dlls in the corresponding versions and somehow executing or injecting them into Testing.exe but I think this is very complicated since it involves system dlls such as KernelBase.dll, Kernel32.dll and ntdll.dll

in view of all this it seems simpler to continue creating a new analyzer 😞

Edited by JeanxPereira
  • Engineer
Posted (edited)

Isn't the parser log half the battle?

enum, bool,  bool,  bool,  bool, Enum, float, member_key, ...
(member_key = string)

Btw, I'm a little bit surprised that no one active on the discord has a complete Testing (with the required dll) since it's the basic tool to start with.

(And dalkon is gone for good without a trace?)

 

edit: well, I've tracked it down to the dll name(s), hopefully.

I would have spared some hours if I had set a breakpoint to

call qword ptr ds:[&LdrLoadDll]

from  the very beginning.

Finally call qword ptr ds:[&RtlNtStatusToDosError] displays the error "...DLL_NOT_FOUND" for

api-ms-win-core-fibers-l1-1-1

because  there's api-ms-win-core-fibers-l1-1-0

only in the windows SysWOW64 folder.

Testing seems to look for api-ms-win-core-localization-l1-2-1.dll also

while there's the l1-2.0 version only.

So far so bad; the really annoying thing is that in Testing.exe only dlls of type l1-1-0.dll are listed.

So why then the l1-1-1.dlls are requested on debugging?

I thought to create copies of l1-1-0.dlls and rename them to l1-1-1.dlls

but at this point I think we should stop that nonsense.

 

Testing 5x.png

Edited by shak-otay
  • Like 1
Posted (edited)
10 hours ago, shak-otay said:

Finally call qword ptr ds:[&RtlNtStatusToDosError] displays the error "...DLL_NOT_FOUND" for

api-ms-win-core-fibers-l1-1-1

because  there's api-ms-win-core-fibers-l1-1-0

only in the windows SysWOW64 folder.

Testing seems to look for api-ms-win-core-localization-l1-2-1.dll also

nice!
on my pc I can find the dlls in both System32/downlevel and SysWOW64/downlevel

I tried copying them to the same directory as the executable but it still doesn't do anything, im using this arguments on command-line:
"D:\DalkonParser\Testing.exe" "D:\SporeModderFX\Projects\AssetData_Binary\animations\PC_EL_fireRavager.Noun" noun xml
image.thumb.png.dfd5d5d99e3c350ad7943aab14459ca4.png

api-ms-win-core-fibers-l1-1-1.dll and api-ms-win-core-localization-l1-2-1.dll.zip

Edited by JeanxPereira
  • Like 1

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...