Closed icex2 closed 1 year ago
In GitLab by @Corin on Jul 22, 2022, 14:37
So 2 things I've noticed with this.
1: (should've noticed earlier) it's just using the eamid for the pcbid, not the pcbid field.
2: this byte remapping is the exact same as the pcbid checksum order: 1, 7, 6, 5, 4, 3, 2
Perhaps something is getting mixed up along the way?
In GitLab by @33c17f40 on Jul 22, 2022, 18:09
I mentioned it to Ice in a DM on Discord but I don't think this is a bug and you should debug the game's code to figure out how it's generating the srcid exactly. Speaking of some recent experience with some Python 1/2 stuff because that's fresh in my head: the Python 1/2 games would create the "display" format of the dongle by taking the middle 6 bytes of the ID (so, skipping the header 01 and the ending checksum byte), shuffling those around, and then putting "01 40" (hardcoded) at the beginning.
I haven't seen any code in btools that would make that format out of a pcbid/eamid. I feel pretty good saying that what you're seeing is probably just how the game generates the srcid from the dongle data.
In GitLab by @33c17f40 on Jul 22, 2022, 21:56
I had some free time so I checked it out in Ghidra. For ddr_2009063000 the relevant func is at 0x50f480.
As I suspected, the game is generating the values based on the dongle payload.
Generating /env/profile/sysid
("eamid"):
str_snprintf(local_30,0x20,"0140%02X%02X%02X%02X%02X%02X%02X%02X",*(undefined *)secplug_data
,*(undefined1 *)((int)secplug_data + 6),*(undefined1 *)((int)secplug_data + 5),
*(undefined *)(secplug_data + 1),*(undefined1 *)((int)secplug_data + 3),
*(undefined1 *)((int)secplug_data + 2),*(undefined1 *)((int)secplug_data + 1),
*(undefined1 *)((int)secplug_data + 7));
std_setenv("/env/profile/sysid",local_30);
log_body_misc("device"," network :%s",local_30);
Generating /env/profile/softid
("pcbid") + /env/profile/mcode
:
str_snprintf(local_30,0x20,"0140%02X%02X%02X%02X%02X%02X%02X%02X",*(undefined *)secplug_data
,*(undefined1 *)((int)secplug_data + 6),*(undefined1 *)((int)secplug_data + 5),
*(undefined *)(secplug_data + 1),*(undefined1 *)((int)secplug_data + 3),
*(undefined1 *)((int)secplug_data + 2),*(undefined1 *)((int)secplug_data + 1),
*(undefined1 *)((int)secplug_data + 7));
std_setenv("/env/profile/mcode",local_64);
std_setenv("/env/profile/softid",local_30);
log_body_misc("device"," software:%s",local_30);
If the mcode inside the dongle is "@@@@@@@@" then it goes down the eamid/sysid path, otherwise it takes the mcode and generates the pcbid/softid from the dongle serial ID inside the dongle payload.
For reference, this is the code that generates the dongle payload: https://dev.s-ul.net/djhackers/bemanitools/-/blob/master/src/main/ddrhook-util/p3io.c#L122-L150
So everything is working as intended. pcbid and eamid are used to generate the dongle payloads in the tools but the game itself has its own way of interpreting the pcbid and eamid embedded in the dongle payloads.
The only way I can imagine you getting it to work the way you are expecting is to do something like hook std_setenv
and change all references to softid
and sysid
to what you want but that's a hack and I wouldn't really recommend.
Edit: To be more explicit, any attempts to change the way this works in bt5 for use with networks will mean that you're breaking support with other tools (if that matters at all), and more importantly with real hardware. Unscramble the srcid (scramble order is 1 7 6 5 4 3 2 8), prepend the expected 0x01 (if you allow any other value besides 01 at the beginning of the PCBID then you'll have to bruteforce it) and then generate the CRC value for the last byte to convert the srcid back into the pcbid format you're used to working with.
In GitLab by @Corin on Jul 22, 2022, 23:20
Yeah I'm not here to break support.
I didn't realise that older games behaved like this and you're right about breaking actual hardware, no point having it behave differently.
My "hack" was basically what you mention:
$pcbid_array = str_split(Core::$pcb_id, 2);
$map = [2, 8, 7, 6, 5, 4, 3, 9];
$reconstructed_pcbid = "";
foreach ($map as $map_key) {
$reconstructed_pcbid .= $pcbid_array[$map_key];
}
Core::$pcb_id = PcbId::generate($reconstructed_pcbid);
I guess it's not so much a hack but actually the proper way to do it then in that case.
In the case of this then I'll close this issue, thanks for clearing things up!
In GitLab by @Corin on Jul 21, 2022, 24:05
Summary
Network srcid doesn't match the specified pcbid
Expected behavior
The sent srcid should match the pcbid
Current behavior
example: pcbid
01B5B1B6EC3A72D418C9
eamid0101020304050607086F
The output in srcid is
01400107060504030208
Now, changing this to: pcbid
01B5B1B6EC3A72D418C9
eamid01B5B1B6EC3A72D418C9
We instead see
0140B5D4723AECB6B118
You can see the characters are still in there but it looks like it's getting mangled between the two of them.
Detailed Description
Implementing network for X currently and weirdly we're seeing strange results from the srcid output.
It doesn't seem to actually be following what's defined in ddrhook for pcbid.
Even weirder, the srcid seems to change when the eamid is changed too.
Steps to reproduce
Stock config outside of pcbid/eamid, sniff the network and you'll see the results of this
01B5B1B6EC3A72D418C9
0101020304050607086F
01400107060504030208
Context (Environment)
Bemanitools version(s) affected
Game(s) and version(s) affected