atom0s Moderator Reputation: 198
Joined: 25 Jan 2006 Posts: 8516 Location: 127.0.0.1
|
Posted: Sun Dec 11, 2016 9:06 pm Post subject: |
|
|
The STL is a messy jungle to attempt to dig into and find things efficiently.
Hooking new/malloc is a bit risky in the attempt to specifically monitor for a specific vectors data, as you will see all allocations for anything that invokes the memory allocations.
In a lot of cases, STL objects will use generalized functions similar to how classes are built after compiling. An object will be passed to the general function that is reused for all other similar parent objects. Meaning you will have to track the creation of the parent object and then monitor for that specific parent within the functions each time they are called to ensure its a call for the one you want to watch.
For example, take the following code:
Code: |
#include <Windows.h>
#include <ctime>
#include <vector>
int __cdecl main(int argc, char* argv[])
{
::srand(::time(nullptr));
std::vector<wchar_t> test1;
std::vector<wchar_t> test2;
// Push a random unicode char to both vectors..
test1.push_back((wchar_t)(97 + ::rand() % 26));
test2.push_back((wchar_t)(97 + ::rand() % 26));
// Clear both vectors..
test1.clear();
test2.clear();
return 0;
}
|
Disassembled while compiled in release mode, you will get the following:
Code: |
int sub_401000()
{
unsigned int v0; // eax@1
int v1; // esi@1
int v2; // ST04_4@1
int v3; // eax@1
int v4; // esi@3
int v5; // ecx@3
__int64 v7; // [sp+Ch] [bp-28h]@1
int v8; // [sp+14h] [bp-20h]@1
__int64 v9; // [sp+18h] [bp-1Ch]@1
int v10; // [sp+20h] [bp-14h]@1
int v11; // [sp+30h] [bp-4h]@1
// ::srand(::time(nullptr));
v0 = time64(0);
srand(v0);
// std::vector<wchar_t> test1;
// std::vector<wchar_t> test2;
v10 = 0;
_mm_storel_epi64((__m128i *)&v9, 0i64);
v9 = 0i64;
v10 = 0;
v11 = 0;
_mm_storel_epi64((__m128i *)&v7, 0i64);
v7 = 0i64;
v8 = 0;
// test1.push_back((wchar_t)(97 + ::rand() % 26));
// test2.push_back((wchar_t)(97 + ::rand() % 26));
LOBYTE(v11) = 1;
v1 = rand() % 26 + 97;
sub_4011A0(v2);
v3 = HIDWORD(v9);
if ( HIDWORD(v9) )
*(_WORD *)HIDWORD(v9) = v1;
HIDWORD(v9) = v3 + 2;
v4 = rand() % 26 + 97;
sub_4011A0(v5);
if ( HIDWORD(v7) )
*(_WORD *)HIDWORD(v7) = v4;
HIDWORD(v9) = v9;
HIDWORD(v7) = v7;
// test1.clear();
// test2.clear();
sub_401120(&v7);
sub_401120(&v9);
return 0;
}
|
As you can see, the same functions are reused for both vectors due to how reused code works. So you would ideally target the 'sub_4011A0' function here to hook push_back and monitor the data being pushed into the vector.
So you would hook 'sub_4011A0' then monitor which vector pointer is being used with the function to ensure it is the vector you are wanting to monitor.
Keep in mind the disassembly is not 100% accurate to what is going on and is more or less a rough / psuedo idea of whats going on.
_________________
- Retired. |
|