繁体   English   中英

转换为ctypes,但我不知道这些函数在做什么

[英]Converting to ctypes but I don't know what these functions are doing

我想知道这里的功能是什么:

  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);
    }
  }

老实说,我不知道函数在哪里开始,在哪里结束以及是否返回任何东西。

完整的代码如下。 我有一个不错的开始,因为我将下面使用的所有winapi函数都已转换为js-ctypes。 这是我到目前为止的内容: 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;
}

似乎您需要学习C ++中的类。 您正在查看的是两个功能。 第一个称为ralloc_t ,它是类的构造函数。 第二个称为~ralloc_t ,它是类的析构函数。

  // This is the constructor
  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!");
    }
  }

  // This is the destructor
  ~ralloc_t()
  {
    buffers_t::reverse_iterator i = buffers_.rbegin(), e = buffers_.rend();
    for (; i != e; ++i) {
      free(i->first);
    }
  }

请注意,构造函数的名称与该类的名称相同(请参见行class ralloc_t ),而析构函数的名称相同,但以波浪号( ~ )为前缀。

这些函数本质上不会返回任何内容。 构造函数的目的是在构造对象时初始化ralloc_t类型的对象,而析构函数的目的是在销毁对象时对其进行清理。

例如,您可能有一个类似于以下内容的代码块:

{
  ralloc_t my_ralloc(some_hwnd);
  // ...
}

作为my_ralloc声明的结果而调用构造函数(将some_hwnd作为构造函数的参数传递)。 析构函数将在块的末尾被调用,这是变量超出范围并被销毁的时候。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM