Author Topic: VOL search list stuff, from PM  (Read 1659 times)

Offline BlackBox

  • Administrator
  • Hero Member
  • *****
  • Posts: 3093
VOL search list stuff, from PM
« on: December 10, 2004, 02:43:41 PM »
at address 004E38B0 there is an array of structures (I termed them VolSearchEntry structures), that would look like this:


Code: [Select]
typedef struct _VolSearchEntry {
   char *pFileName;
   int unknown1;
   int flags;
   int unknown2;
} VolSearchEntry;

pFileName points to the ascii string holding the vol filename.
unknown1 and unknown2 are always set to 0, the flags (if that's what it really is) always is set to 1.

The code which iterates thru this list is pretty straightforward, it only took a few minutes to figure it out. (Look in ResManager::Init() right past the CD check stuff, where it references that address up above).

The list in the EXE contains 6 elements (the first 5 being references to the VOL's, the last one is a termination of some sort. The address, and unknowns 1 and 2 are 0 but the flags is still 1).

This is somewhat interesting/odd, as well. This value occurs immediately after the VOL search list.

Code: [Select]
  .text:0047111D                 cmp     edi, offset dword_4E3910 



This is a snippet from IDA if you didn't already notice. the dword_4E3910 represents address 004E3910 (if you didn't notice that)

Looking at the data section at this address, I found:

Code: [Select]
 .data:004E3910 dword_4E3910    dd 193948Ah           ; DATA XREF: ResManager::Init(void)+1ADo
.data:004E3910                                       ; ResManager::VerifyCD(void)+85r

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4955
VOL search list stuff, from PM
« Reply #1 on: December 10, 2004, 09:34:06 PM »
This looks like that pm you sent me earlier (oh, it is). I've figured out a little more the past few days. And yeah, it looks like there is an unused entry. It looks like it would work if you just filled it in.

The unknown1 in that struct is a VolFile* from my post on the vol file internal layout stuff.

Quote
CODE 
 .text:0047111D                 cmp     edi, offset dword_4E3910 
That's just the ending address of the list. Kinda like using a for loop with the addresses rather than the index. You'll note it refers to the byte after the end of the table. Kinda like coding:

Code: [Select]
for (addr = &array[0]; addr < &array[NUM_ELEMENTS]; addr++)


There is similar code in the OpenStream function. I've already annotated it so maybe it'll help.

Quote
004711D7  XOR EDI,EDI                              ;  Search loaded Vol files for resource; Clear LoopCounter
004711D9  MOV EBX,Outpost2.004E38B4                ;  Load base address of Vol filename/attribute table
004711DE  /MOV ECX,DWORD PTR DS:[EBX]              ;  Load VolFileTable object pointer
004711E0  |TEST ECX,ECX                            ;  Check if VolFile* == NULL
004711E2  |JE Outpost2.00471268                    ;  -> NextLoopIteration (VolFile* == NULL)
004711E8  |MOV EAX,DWORD PTR DS:[ECX]              ;  Load VolFile.vtbl
004711EA  |CALL DWORD PTR DS:[EAX]                 ;  VolFile.GetStatus()
004711EC  |TEST EAX,EAX                            ;  Check if streamStatus == StreamNoError
004711EE  |JE SHORT Outpost2.0047120C              ;  -> Skip (StreamNoError)
004711F0  |CMP EAX,2
004711F3  |JE SHORT Outpost2.0047120C
004711F5  |MOV ECX,DWORD PTR DS:[EBX]              ;  Load VolFileTable object pointer
004711F7  |PUSH ESI                                ;  Arg1 - param1 (char const * resName)
004711F8  |MOV EAX,DWORD PTR DS:[ECX]              ;  Load VolFile.vtbl
004711FA  |CALL DWORD PTR DS:[EAX+28]
004711FD  |TEST EAX,EAX                            ;  Check if VolFile does not contains the desired resource
004711FF  |JE SHORT Outpost2.00471268              ;  -> NextLoopIteration
00471201  |SHL EDI,4                               ;  EDI := table offset to VolFile/attributes/filename entry
00471204  |MOV EAX,DWORD PTR DS:[EDI+4E38B4]       ;  Load VolFileTable object pointer (which are StreamIO's)
0047120A  |JMP SHORT Outpost2.0047127A             ;  -> Return EAX
0047120C  |LEA EAX,DWORD PTR SS:[ESP+14]           ;  Load &local2 (filePath - string buffer)
00471210  |MOV ECX,DWORD PTR DS:[EBX-4]            ;  Load VolFileTable.volFileName (char *)
00471213  |PUSH EAX                                ; /Arg2 - filePath (char *)
00471214  |MOV EBP,0                               ; |
00471219  |PUSH ECX                                ; |Arg1 - volFileName (char *)
0047121A  |MOV ECX,DWORD PTR SS:[ESP+18]           ; |Load "this" pointer (ResManager)
0047121E  |CALL Outpost2.?GetFilePath@ResManager@@>; \?GetFilePath@ResManager@@QAEHPBDPAD@Z
00471223  |PUSH 980                                ;  Arg1 - 2432 (0x980) numBytesToAlloc
00471228  |CALL Outpost2.004C0F40                  ;  MemAlloc
0047122D  |ADD ESP,4                               ;  Cleanup parameters on stack (MemAlloc)
00471230  |MOV ECX,EAX                             ;  Load "this" pointer (VolFile) - allocated memory
00471232  |TEST ECX,ECX                            ;  Check if allocated memory pointer == NULL
00471234  |JE SHORT Outpost2.0047123D              ;  -> Skip (allocated memory pointer == NULL)
00471236  |CALL <Outpost2.VolFile.constructor()>
0047123B  |MOV EBP,EAX                             ;  EBP := returned VolFile*
0047123D  |LEA EAX,DWORD PTR SS:[ESP+14]           ;  Load &local2 (filePath - string buffer)
00471241  |MOV ECX,EBP                             ;  Load "this" pointer (VolFile)
00471243  |PUSH EAX                                ; /Arg1 - volFile (char *)
00471244  |CALL <Outpost2.VolFile.OpenFile(char *v>; \Outpost2.004A0AE0
00471249  |TEST EAX,EAX
0047124B  |JE SHORT Outpost2.0047125A
0047124D  |PUSH ESI                                ;  Arg1 - resName (char const *)
0047124E  |MOV EAX,DWORD PTR SS:[EBP]              ;  Load VolFile.vtbl
00471251  |MOV ECX,EBP                             ;  Load "this" pointer (VolFile)
00471253  |CALL DWORD PTR DS:[EAX+28]              ;  VolFile.OpenStream(char const *resName)
00471256  |TEST EAX,EAX                            ;  Check for success
00471258  |JNZ SHORT Outpost2.00471287             ;  -> Success (Break); EndOfLoop (return EBP)
0047125A  |TEST EBP,EBP                            ;  Check if VolFile* == NULL
0047125C  |JE SHORT Outpost2.00471268              ;  -> Skip (NextLoopIteration) (VolFile* == NULL)
0047125E  |PUSH 1                                  ;  Arg1 - 1 (???)
00471260  |MOV EAX,DWORD PTR SS:[EBP]              ;  Load VolFile.vtbl
00471263  |MOV ECX,EBP                             ;  Load "this" pointer (VolFile)
00471265  |CALL DWORD PTR DS:[EAX+4]
00471268  |ADD EBX,10                              ;  Next Vol filename/attribute entry
0047126B  |INC EDI                                 ;  LoopCounter++
0047126C  |CMP EBX,Outpost2.004E3904               ;  Check if end of table has been reached (4E3904 is the address of the "entry" just past the end of the table)
00471272  \JB Outpost2.004711DE
00471278  XOR EAX,EAX                              ;  Return 0


I'll probably be posting an updated OllyDbg comment file soon. I've added a fair bit these last few days. (Plus, it's hard to read in these posts)
« Last Edit: December 10, 2004, 09:35:07 PM by Hooman »