Runaway girl and me (.gpx)

Extraction and unpacking of game archives and compression, encryption, obfuscation, decoding of unknown files
Senki
Posts: 2
Joined: Wed May 18, 2022 6:34 pm

Runaway girl and me (.gpx)

Post by Senki »

Hi, I'm having trouble extracting the text files/script from the archive this vn engine is using, engine is probably https://github.com/rinkako/YuriAVGEngine, not 100% sure.
I've tried the usual methods using quickbms comtype scan, I went over all the dumps but didn't find any readable strings.
All the resources online didn't get it done, arc_unpacker etc, couldn't do it.
Archive is probably related to (.gxp) format viewtopic.php?t=3302
https://github.com/morkt/GARbro/blob/ma ... /ArcGXP.cs
I've tried extracting it using those files and it didn't work either.
Eventually I tried going with a debugger/decompiler to see what the executable is doing to the archive but I couldn't figure it out.
I can attach the game exe and a fully decompiled exe into c with hexrays if that's allowed.

Files in question:
https://www59.zippyshare.com/v/JYWLzmIj/file.html
https://www68.zippyshare.com/v/aOa4PIBH/file.html
I tried uploading using the built in uploader but it said the extension was not allowed, I checked the rules and it should be fine so I uploaded it to zippyshare.

Would appreciate help with this.
Thank you.


I just double checked and It's definitely mentioning the use of .mwb
Image

So it's related to that (.gxp) engine for sure.
Senki
Posts: 2
Joined: Wed May 18, 2022 6:34 pm

Re: Runaway girl and me (.gpx)

Post by Senki »

I've found out that the dev released an update for the game to include a partial English translation.
I've used this to make a comparison between the files:
Image

Not sure what that C3 stands for, file size maybe? a checksum? still figuring this out but size seems likely.

I've looked and there seems to be different chunks of 120 bytes (78h) and then a matched section of 10 bytes (Ah)
Image

Seems to line up with whatever is happening in the Function IDA found:
Image
esp+40h+block which is 4+40+34 which is 78h just like I saw in the file comparison

This is the psuedocode:

Code: Select all

//----- (00474350) --------------------------------------------------------
int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
  void **v4; // eax
  void **v5; // eax
  void **v6; // eax
  void **v7; // eax
  size_t v8; // ecx
  void **v9; // esi
  CHAR *v11; // [esp-18h] [ebp-58h] BYREF
  int v12; // [esp-14h] [ebp-54h]
  int v13; // [esp-10h] [ebp-50h]
  wchar_t *v14; // [esp-Ch] [ebp-4Ch]
  void **v15; // [esp-8h] [ebp-48h]
  size_t v16; // [esp-4h] [ebp-44h]
  void *Block[4]; // [esp+Ch] [ebp-34h] BYREF
  size_t v18; // [esp+1Ch] [ebp-24h]
  unsigned int v19; // [esp+20h] [ebp-20h]
  void *v20[4]; // [esp+24h] [ebp-1Ch] BYREF
  int v21; // [esp+34h] [ebp-Ch]
  unsigned int v22; // [esp+38h] [ebp-8h]

  nullsub_1();
  sub_5B1160(314572800);
  sub_5B1060(1572864);
  if ( sub_5C1D80((wchar_t *)aSy_0) )
  {
    v19 = 15;
    v18 = 0;
    LOBYTE(Block[0]) = 0;
    sub_44BDB0(Block, "system_en.gpx", 0xDu);
    v4 = Block;
    v16 = v18;
    if ( v19 >= 0x10 )
      v4 = (void **)Block[0];
    v15 = v4;
    v14 = (wchar_t *)aSy_0;
  }
  else if ( sub_5C1D80((wchar_t *)aSy_1) )
  {
    sub_44BEB0(Block, "system_cns.gpx");
    v5 = Block;
    v16 = v18;
    if ( v19 >= 0x10 )
      v5 = (void **)Block[0];
    v15 = v5;
    v14 = (wchar_t *)aSy_1;
  }
  else if ( sub_5C1D80((wchar_t *)aSy_2) )
  {
    sub_44BEB0(Block, "system_cnt.gpx");
    v6 = Block;
    v16 = v18;
    if ( v19 >= 0x10 )
      v6 = (void **)Block[0];
    v15 = v6;
    v14 = (wchar_t *)aSy_2;
  }
  else
  {
    sub_44BEB0(Block, "system.gpx");
    v7 = Block;
    v16 = v18;
    if ( v19 >= 0x10 )
      v7 = (void **)Block[0];
    v15 = v7;
    v14 = (wchar_t *)&off_76E754;
  }
  sub_5B04A0(v14, v15, v16);
  if ( v19 >= 0x10 )
    j__free(Block[0]);
  if ( (dword_820088 & 1) == 0 )
  {
    dword_820088 |= 1u;
    sub_45F850();
    atexit(sub_6C3E10);
  }
  v22 = 7;
  v21 = 0;
  LOWORD(v20[0]) = 0;
  if ( lpCmdLine )
  {
    v16 = 15;
    v15 = 0;
    LOBYTE(v11) = 0;
    if ( *lpCmdLine )
      v8 = strlen(lpCmdLine);
    else
      v8 = 0;
    sub_44BDB0(&v11, lpCmdLine, v8);
    v9 = (void **)sub_5ACBD0(Block, v11, v12, v13, (int)v14, (int)v15, v16);
    if ( v20 != v9 )
    {
      if ( v22 >= 8 )
        j__free(v20[0]);
      v22 = 7;
      v21 = 0;
      LOWORD(v20[0]) = 0;
      sub_40B900(v20, v9);
    }
    if ( v19 >= 8 )
      j__free(Block[0]);
  }
  v16 = 7;
  v15 = 0;
  LOWORD(v11) = 0;
  sub_4049B0((int)&v11, v20, 0, 0xFFFFFFFF);
  if ( sub_45FB80((int)&dword_820090, (int)hInstance, (wchar_t *)v11, v12, v13, (int)v14, (int)v15, v16) )
  {
    sub_461B80((int)&dword_820090);
    sub_460870((int)&dword_820090);
  }
  sub_5B05B0();
  sub_5B0E70();
  if ( v22 >= 8 )
    j__free(v20[0]);
  return 0;
}


Still not really sure what it's doing but I'm getting somewhere I think
I think I will try to modify the GARbro ArcGXP.cs script to accept these changes whenever I find them, if I will that is.
Arcrska
Posts: 1
Joined: Thu Aug 18, 2022 12:04 pm

Re: Runaway girl and me (.gpx)

Post by Arcrska »

Hello there, I got the packer and .mwb extractor here(I'm not the one written it), it only works for AVGX_V2, the game uses V3 so it needs updating, I'll include the source code along with the tool too