I was wondering what this function here does:
ralloc_t(HWND hwnd) : proc_(0)
{
DWORD pid = 0;
if (!GetWindowThreadProcessId(hwnd, &pid)) {
throw exception("dang, no dice");
}
proc_ = OpenProcess(
PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION, FALSE, pid);
if (!proc_) {
throw exception("no open for me!");
}
}
~ralloc_t()
{
buffers_t::reverse_iterator i = buffers_.rbegin(), e = buffers_.rend();
for (; i != e; ++i) {
free(i->first);
}
}
I honestly don't know where function starts and where it ends and if it's returning anything.
The full code is below. I got a decent start on it, in that I have all the winapi functions in use below converted already to js-ctypes. This is what I have so far: https://gist.github.com/Noitidart/f691ab9a750f24be346f
#include <windows.h>
#include <commctrl.h>
#include <iostream>
#include <cstdio>
#include <stdexcept>
#include <map>
using namespace std;
/**
* Allocate/read/write remote process memory.
* The implementation is pretty crappy, as it isn't intelligent at all:
* It always allocates at least a full page per allocation :(
* Do something more clever in production!
* Also, type safety and convenience are pretty lacking.
* But again, this is test code, so it sucks!
*/
class ralloc_t
{
public:
ralloc_t(HWND hwnd) : proc_(0)
{
DWORD pid = 0;
if (!GetWindowThreadProcessId(hwnd, &pid)) {
throw exception("dang, no dice");
}
proc_ = OpenProcess(
PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION, FALSE, pid);
if (!proc_) {
throw exception("no open for me!");
}
}
~ralloc_t()
{
buffers_t::reverse_iterator i = buffers_.rbegin(), e = buffers_.rend();
for (; i != e; ++i) {
free(i->first);
}
}
void* alloc(size_t size)
{
void* rv = VirtualAllocEx(
proc_, 0, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (!rv) {
throw bad_alloc();
}
buffers_.insert(make_pair(rv, size));
return rv;
}
template <typename T>
T* create(size_t elems = 1)
{
return (T*)alloc(elems * sizeof(T));
}
void free(void* p)
{
buffers_t::iterator i = buffers_.find(p);
if (i == buffers_.end()) {
throw exception("invalid buffer");
}
VirtualFreeEx(proc_, i->first, i->second, MEM_RELEASE);
buffers_.erase(i);
}
void read(void* remote, void* local)
{
buffers_t::iterator i = buffers_.find(remote);
if (i == buffers_.end()) {
throw exception("invalid remote read buffer");
}
if (!ReadProcessMemory(proc_, i->first, local, i->second, 0)) {
throw exception("failed to read remote buffer");
}
}
void write(void* remote, const void* local)
{
buffers_t::iterator i = buffers_.find(remote);
if (i == buffers_.end()) {
throw exception("invalid remote write buffer");
}
if (!WriteProcessMemory(proc_, i->first, local, i->second, 0)) {
throw exception("failed to write remote buffer");
}
}
private:
typedef map<void*, size_t> buffers_t;
buffers_t buffers_;
HANDLE proc_;
};
int main()
{
typedef HWND(WINAPI * GetTaskmanWindowPtr)();
try
{
HMODULE user32 = LoadLibrary(L"user32");
GetTaskmanWindowPtr GetTaskmanWindow =
(GetTaskmanWindowPtr)GetProcAddress(user32, "GetTaskmanWindow");
if (!GetTaskmanWindow) {
throw exception("Failed to get GetTaskmanWindow!");
}
HWND htm = GetTaskmanWindow();
if (!htm) {
throw exception("Failed to get taskman window");
}
HWND htb = FindWindowEx(htm, 0, L"ToolbarWindow32", 0);
if (!htb) {
throw exception("Failed to get toolbar window");
}
ralloc_t ralloc(htb);
int count = SendMessage(htb, TB_BUTTONCOUNT, 0, 0);
cout << count << endl;
for (int i = 0; i < count; ++i) {
TBBUTTON tbb;
TBBUTTON* rtbb = ralloc.create<TBBUTTON>();
BOOL rv = SendMessage(htb, TB_GETBUTTON, i, (LPARAM)rtbb);
ralloc.read(rtbb, &tbb);
ralloc.free(rtbb);
cout << rv << " " << sizeof(tbb) << " " << tbb.idCommand << " "
<< tbb.iString << endl << flush;
int chars = SendMessage(htb, TB_GETBUTTONTEXT, tbb.idCommand, (LPARAM)0);
if (chars <= 0) {
continue;
}
chars++;
wchar_t* rbuf = ralloc.create<wchar_t>(chars);
if (SendMessage(htb, TB_GETBUTTONTEXT, tbb.idCommand, (LPARAM)rbuf) > 0) {
wchar_t* buf = new wchar_t[chars];
ralloc.read(rbuf, buf);
wcout << buf << endl << flush;
delete[] buf;
}
}
}
catch (const exception& ex)
{
cerr << "Error: " << ex.what() << endl;
}
// Sleep
getchar();
return 0;
}