Basic theory is this.
There are functions in wow that loop over the object list (duh). Apparently there is more than one. Anyway.
Patch one of those functions to run our own byte code. The byte code will copy a (the) register to a buffer inside the bytecode. (it will also keep a counter variable at the very end of the bytecode)
Problem: There is no way to know when the wow function is done running, which means all we can do is blindly read the buffer. But I think there are ways to make sure you get an up-to-date list. If you make the buffer long enough (ie. 2x actual object list length) the wow function will run multiple times and fill the buffer, basically treating it like a circular stack. The 2x length is crucial. Basically there will be 2 very similar lists in the buffer, once you figure out where each one is, you have 2 copies of the list: 1 old complete list, 1 new and possibly incomplete.?
I'm stuck on the actual codecave code atm. Just trying to copy a register to array. Haven't got it yet.
Code:
'_codeCaveCtrLoc = end of the buffer - 4 'ie. Int32
'_codeCaveDumpStart = _codeCaveStart + 200 'assuming 200 bytes is enough for my code
'_objMgrListGiveAddr = wow.exe code that uses a register to store object.baseaddress
.AppendLine("push eax")
.AppendLine("push ebx")
.AppendLine("push ecx")
''Check counter
.AppendLine("mov eax, " & _codeCaveCtrLoc.ToInt32.ToString)
.AppendLine("mov ebx, [eax]") 'ebx = curIndex
.AppendLine("cmp ebx, 999") '
.AppendLine("jle 6") 'If
.AppendLine("mov [eax], 0") 'reset index
.AppendLine("add [eax], 1") 'Else increment index
''write ebx to list
''ebx = _codeCaveDumpStartLoc + (indx * 4)
.AppendLine("mov ebx, " & _codeCaveDumpStartLoc.ToInt32.ToString)
.AppendLine("mov ecx, [eax]")
.AppendLine("add ebx, ecx * 4") 'howto?
.AppendLine("pop eax")
.AppendLine("mov [ebx], eax") 'magic happens right here
.AppendLine("pop ebx")
.AppendLine("pop ecx")
.AppendLine("jmp " & _objMgrListGiverAddr.ToInt32.ToString)
* 999 is hardcoded. will change to some MAX_SIZE constant once i feel comfortable I know how big the list gets.
* jle 6 --might not be 6, I'm using fasm_managed (credits*) to assemble the bytecode. Will debug the
byteCode jmps once i get the array index part working.
Any thoughts on the basic principal? (or my asm mistake?)
edit: fixed comments.
*obviously I did the "mov [ecx], 0" wrong. I keep trying to move value/reg/valueOfReg incorrectly. learning. fixed in image 2 comments down.
**jmp was wrong too. I just now started viewing the codecave with CE (because it shows opcodes in assembly too, very nice), and noticed it was
actually jumping backwards! (instead of jumping past the next instruction::how i implement my loop counter)
one thing I'm unsure about: the fixed coded is "jle 20" which is "Jump near if less than or equal to. But the 20 confuses me. it's relative to the beginning of the codecave location not the current instruction location which I thought it would be? It compiles to ** 02 which is "some jmp type" + 02 so it's actually doing what I want, jmping ahead 1 inctruction. just not sure why it's "+20" for the jle, not +02. <--has something to do with how fasm_managed compiles "jle 20" .