# Reversing number

1. ## Reversing number Assuming this code:

int EDI = 0x1505;
for( int i = 0; i < lstrlen(dir); i++ )
{
if ( dir[i] != '.' && dir[i] != '\' )
{
EDX = EDI * 32;
EDX = EDX + EDI;
EDX = EDX + dir[i];
EDI = EDX;
}
}

Is it possible to get the string from the generated number? A game that I am developing uses these numbers to access the files inside a bigger file.
I am trying to create a map-tree view of that file, so I guess I will need to decode the numbers to get the actual path.

I already asked in stackoverflow and didnt get good answers, but one guy said it would be possible and gave a pseudo-code, but I can't make it work.

He said this:
So it would be only possible to reverse strings when dir[i] would be inside a range of 33 (e.g. 0-32 or 97 - 129) and EDX does not overflow.
So, if you could assume that the string only has minuscles (which are ascii 97-122, it might be possible:

• First, subtract 0x1505 from VAL
• Then, calculate ch = VAL % 33
• Calculate ch = ch + n*33. Choose n in a way to get ch into the range 97-129, this is the next char.
• Subtract this char from VAL and divide by 33: VAL = (VAL - ch) / 33
• Iterate from step 2 until VAL is 0.

This can be further improved by bringing ch into other ranges of the ascii range (e.g. numbers, uppercase letters) if you feel, that the calculated char is incorrect. But this makes the algorithm heuristic then.

I did this ([C++] int Find_N_Number(unsigned int value) { int MaxRange = 129; int MinRange = - Pastebin.com) but "2520255578" is not returning the correct string, which would be "data\map\realworld_r\01_yokohama\105\map_data\105.emr". (Without " )  Reply With Quote

2. ## Re: Reversing number

And you are sure the given function works correct?

I can't seem to reproduce the given path to that certain number.

- - - Updated - - -

Uhm, the number "2520255578" is incorrect.

Worked on it some more and the function you provided works like how that dude explains (sort of).
It had some minor issues like his first step.

For me it works, encoding and decoding, except that number of yours :p

Comment rule 35 and uncomment rule 36 to run it with your number.

PHP Code:
``` <?php    /*    int EDI = 0x1505;    for( int i = 0; i < lstrlen(dir); i++ )    {        if ( dir[i] != '.' && dir[i] != '\' )        {            EDX = EDI * 32;            EDX = EDX + EDI;            EDX = EDX + dir[i];            EDI = EDX;        }    }    */    \$dir = 'test\data';    \$EDI = 0x1505;        for (\$i = 0; \$i < strlen(\$dir); \$i++) // STRLEN    {        if (\$dir[\$i] != '.' && \$dir[\$i] != '\\')        {            \$a = \$EDI * 32;            \$b = \$a + \$EDI;            \$c = \$b + ord(\$dir[\$i]);                        \$EDI = \$c;        }    }        echo 'result: ' . \$EDI . PHP_EOL;    \$value = \$EDI;    //\$value = 2520255578;        \$result = '';    while (\$value > 0x1505)    {        \$ch = \$value % 33;                while (\$ch < 97)        {            \$ch += 33;        }                if (\$ch > 129)        {            echo 'Data failure ' . \$ch . PHP_EOL;                        exit;        }                \$value = floor((\$value - \$ch) / 33);        \$result .= chr(\$ch);    }        \$result = strrev(\$result);        echo \$result . PHP_EOL; ```  Reply With Quote

3. ## Re: Reversing number

@Joopie

Sorry for the function, but this one is working fine:

Code:
```unsigned int __fastcall sub_4547A0(int a1, const char *a2)
{
unsigned int v2; // edi@1
unsigned int v3; // esi@1
unsigned int v4; // kr00_4@1
int i; // ecx@1
char v6; // al@2
unsigned int v7; // ecx@6
char v8; // al@7

char Dst[0x400];

v2 = strlen(a2);
v3 = 5381;
strcpy_s(Dst, 0x400u, a2);
v4 = strlen(Dst);

for (i = 0; i < (signed int)(v4 + 1); ++i)
{
v6 = *(Dst + i);
if (v6 >= 65 && v6 <= 90)
*(Dst + i) = v6 + 32;
}
v7 = 0;
if (v2)
{
do
{
v8 = *(Dst + v7);
if (v8 != 46 && v8 != 92)
v3 = v8 + 33 * v3;
++v7;
} while (v7 < v2);
}
memset(&Dst, 0, 0x400u);
return v3;
}```
If you do
Code:
```    char dir[] = "data\\map\\realworld_r\\01_yokohama\\105\\map_data\\105.emr";

unsigned int values = sub_4547A0(1, dir);```
You will get that number I told, 2520255578.  Reply With Quote

4. ## Re: Reversing number

Still not able to get to that number, even manually calculating it is failing for me.

PHP Code:
``` v8 = *(Dst + v7);if (v8 != 46 && v8 != 92)    v3 = v8 + 33 * v3;  ```

Code:
```d = 100
a = 97
t = 116
a = 97

result = 5381

result (177673) = d (100) + 33 * result (5381)
result (5863306) = a (97) + 33 * result (177673)
result (193489214) = t (116) + 33 * result (5863306)
result (6385144159) = a (97) + 33 * result (193489214)

result (6.385.144.159) > 2.520.255.578```
Or I'm just doing something wrong, which is also a possibility!  Reply With Quote

5. ## Re: Reversing number

Are you using Multi-Byte charset? I don't know but that might be an issue...

I also tried to run your PHP code, it didn't matched too. lol

But it is really weird that for me its an output and for you another one... weird.  Reply With Quote

6. ## Re: Reversing number

Well, the number got overflow and the steps are continued. The "formula" dont care about the overflow, so you cant deduce that your formula is incorrect just by the path: "data".  Reply With Quote

7. ## Re: Reversing number Originally Posted by Cainan Kenji Well, the number got overflow and the steps are continued. The "formula" dont care about the overflow, so you cant deduce that your formula is incorrect just by the path: "data".
My point was that when you do the data part, you already had a bigger number than he stated. My reason of saying so was, like you pointed out, that I never thought about a overflow. Thanks for pointing that out.

So I guess in [C++] int Find_N_Number(unsigned int value) { int MaxRange = 129; int MinRange = - Pastebin.com remove line 28 and change the condition of the do while loop on line 41 to "value != 5381" it might work?
.. I think  Reply With Quote

8. ## Re: Reversing number

I tested here and it does not work, it shows "hi{d", the inverse of the old code.  Reply With Quote

9. ## Re: Reversing number Originally Posted by Cainan Kenji I tested here and it does not work, it shows "hi{d", the inverse of the old code.

It works if you have the whole number.

Code:
```38260988133767770757751706102424708488397652359015616981186101000246135898
// above number mod 4294967296 (2 ^32) which is the max value for a unsigned interger you get 2520255578

Also because the function adds 32 to the characters between 65 ... 90 and skips out the characters 46 "." and 92 "" you can't reconstruct the truely original string.

I think you have to rework you approach on how you're going to make that tree view.

Spoiler:

The python test code

PHP Code:
``` def encode(string):    result = 5381        for i in range(len(string)):        char = ord(string[i])                if char >= 65 and char <= 90:            char += 32                    if char != 46 and char != 92:            result = (char + 33 * result)        return resultdef decode(number):    result = ""        i = 0    while number != 5381:        char = number % 33;                while char < 97:            char += 33                    if char > 129:            print("Data failure {0}".format(char))                        exit()                    number = (number - char) / 33                result += chr(char)            return resultencoded = encode("data\\map\\realworld_r\\01_yokohama\\105\\map_data\\105.emr")print(encoded)print(encoded % 4294967296) # mod for making a unsigned int (32bit)print(decode(encoded))  ```  Reply With Quote

10. ## Re: Reversing number

What game is this? I might have a useful solution.  Reply With Quote

11. ## Re: Reversing number

@dTantra Originally Posted by dTantra What game is this? I might have a useful solution.
The game is Digimon Masters Online  Reply With Quote

12. ## Re: Reversing number Originally Posted by SheenBR @dTantra The game is Digimon Masters Online
Is the feature in question version dependent? If so what version are you using? Also if you have a current unpacked exe or an exe that launches with arguments for debugging purposes that would be helpful. Also an outline of your current goal or why you need this information, just because I may be able to come up with a different solution for the same problem. I had assumed you were trying to unpack the packing system. Nevermind about the outline, I see what you are attempting to do, I am testing things now.  Reply With Quote

13. ## Re: Reversing number Originally Posted by SheenBR @dTantra The game is Digimon Masters Online
Here is roughly 9,000 of them so far. pastebin - dmo files - post number 3467179 I will have a lot more shortly :)  Reply With Quote

14. ## Re: Reversing number Originally Posted by dTantra Here is roughly 9,000 of them so far. pastebin - dmo files - post number 3467179 I will have a lot more shortly :)
Can you tell us/me how you did it?  Reply With Quote

15. ## Re: Reversing number Originally Posted by Joopie Can you tell us/me how you did it?
Haha sure, I just used a different approach since generating the string from the hash is not really on the table at this time.

First list itself is generated from the game launcher / updater. I CC'ed the function that processes the files and dumped the hash + hashed content to file for every file patched since version 99 (earliest I can tell). This resulted in the 9k some entries, but only works for patched content which does not cover everything since it only resulted in 2gb-3gb worth of content vs the 5gb that the game has.

I had to find another way to get the rest..

Since the client requests them every time it needs one, I simply CC'ed the function that is called and dumped the hash + the hashed content to file. This allows you to walk around in game wherever you want the files for or near people with equipment etc. or whatever your desires to capture them.

General code can be found below, while not the cleanest, it gets the job done.

Code:
```struct FileInfo
{
DWORD Hash;
const char * Filename;
};

FileInfo cFileInfo;

void ProcessFileHashInfo()
{
ofstream myfile;
myfile.open("filenames.txt", std::ios_base::app);
myfile << cFileInfo.Hash << "\t" << cFileInfo.Filename << "\n";
myfile.close();
}

__declspec(naked) void CC_ExtractFileHashInfo(void)
{
__asm
{
PUSH  0x00A04148
POP cFileInfo.Filename
PUSH cFileInfo.Filename
MOV cFileInfo.Hash, EDX
PUSHFD
}
ProcessFileHashInfo();
__asm
{
POPFD  Reply With Quote