-
Warden Scan Length
I looked over this function long ago and I remember that the length passed would suffice. I started reversing a 2.4.3 warden module and decided to look over this function once again. Based off the asm the length will always be a multiple of 4, unless it's less than 4. The thing that I don't get is that I have logged multiple scans with lengths that are not multiples of 4. For example, 6 >> 2 * 4 = 4, why do they request something like that? Or am I reading the code wrong? The only problem with my current code is it could overwrite another buffer, unless it allocates the correct length. The server must do a check or the scan would fail for everyone.
Code:
seg000:00005F06 _Buffer = dword ptr 4
seg000:00005F06 _Address = dword ptr 8
seg000:00005F06 _Length = dword ptr 0Ch
seg000:00005F06
seg000:00005F06 push esi
seg000:00005F07 push edi
seg000:00005F08 cld
seg000:00005F09 mov edx, [esp+14h]
seg000:00005F0D mov esi, [esp+10h]
seg000:00005F11 mov eax, [esp+0Ch]
seg000:00005F15 mov ecx, edx
seg000:00005F17 mov edi, eax
seg000:00005F19 shr ecx, 2
seg000:00005F1C jz short loc_5F20
seg000:00005F1E rep movsd
seg000:00005F20
seg000:00005F20 loc_5F20: ; CODE XREF: +16j
seg000:00005F20 mov cl, 3
seg000:00005F22 and ecx, edx
seg000:00005F24 jz short loc_5F28
seg000:00005F26 rep movsb
seg000:00005F28
seg000:00005F28 loc_5F28: ; CODE XREF: +1Ej
seg000:00005F28 pop edi
seg000:00005F29 pop esi
seg000:00005F2A retn
Last edited by DarkLinux; 07-24-2017 at 03:54 PM.
-
Contributor
1. It's should be the same warden module (i don't know why your address different).
2. It was never been multiple of 4, is just a compiler optimization for "faster"reading. I reads faster 4 bytes at once, then it reads the rest separately.
-
rep loops for ecx amount of times. ecx is shifted by 2 and then reads on a 4 byte boundary, essentially making the size always a multiple of 4.
Code:
seg000:00005F19 shr ecx, 2
seg000:00005F1E rep movsd
is that not what its doing...
-
Contributor
Yes, it first divides by 4 and then it reads (in fact: copies) the result count of dwords.
Don't ignore this part:
Code:
seg000:00005F20 loc_5F20: ; CODE XREF: +16j
seg000:00005F20 mov cl, 3
seg000:00005F22 and ecx, edx
seg000:00005F24 jz short loc_5F28
seg000:00005F26 rep movsb
seg000:00005F28
seg000:00005F28 loc_5F28: ; CODE XREF: +1Ej
When finished reading the 32 bit data (rep movsd), then it reads (copies) the last part (if it exists) as "ecx = edx & 3" count of bytes (max 3) with rep movsb.
Edit: Just found some interesting Hex-Rays Decompiler representation:
Code:
void *__cdecl Warden_CopyMem(void *dest, void *source, unsigned int size)
{
char *source_; // esi@1
void *result; // eax@1
char *dest_; // edi@1
unsigned int dwordsCount; // ecx@1
unsigned int bytesCount; // ecx@3
source_ = source;
result = dest;
dest_ = dest;
dwordsCount = size >> 2;
if ( size >> 2 )
{
qmemcpy(dest, source, 4 * dwordsCount);
source_ = source + 4 * dwordsCount;
dest_ = dest + 4 * dwordsCount;
dwordsCount = 0;
}
LOBYTE(dwordsCount) = 3;
bytesCount = size & dwordsCount;
if ( bytesCount )
qmemcpy(dest_, source_, bytesCount);
return result;
}
Last edited by tutrakan; 07-28-2017 at 04:19 AM.
-
Post Thanks / Like - 1 Thanks
DarkLinux (1 members gave Thanks to tutrakan for this useful post)
-
ah ya, I did not notice the rest from
thanks