MemoryEx.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. //#include "stdafx.h"
  2. #include "MemoryEx.h"
  3. #include "./core/helpfunc.h"
  4. #define push(s,x)s.push_back(x)
  5. #define pop(s) s.back();s.pop_back()
  6. int get_op_prior(wchar_t op) {
  7. if (op == L'+' || op == L'-')
  8. return 0;
  9. if (op == L'*' || op == L'/')
  10. return 1;
  11. return 2;
  12. }
  13. bool is_op(wchar_t op) {
  14. return op == L'+' || op == L'-' || op == L'*' || op == L'/';
  15. }
  16. int do_op(int a, int b, wchar_t op) {
  17. int ans;
  18. if (op == L'+')
  19. ans = a + b;
  20. else if (op == L'-')
  21. ans = a - b;
  22. else if (op == L'*')
  23. ans = a * b;
  24. else if (op == L'/')
  25. ans = a / b;
  26. else
  27. ans = 0;
  28. return ans;
  29. }
  30. //like AA+BB+DD-CC*cc
  31. int stringcompute(const wchar_t* s) {
  32. int ans = 0;
  33. if (!s || !*s)
  34. return 0;
  35. wstring num;
  36. int op;
  37. vector<int> ns;
  38. vector<int> os;
  39. while (*s || !os.empty()) {
  40. if (is_op(*s) || *s == 0) {
  41. int x;
  42. swscanf(num.data(), L"%X", &x);
  43. if (!num.empty()) {
  44. push(ns, x); num.clear();
  45. }
  46. if (ns.empty()) { /// 数字栈空,直接压入数据
  47. push(os, *s);
  48. s++;
  49. }
  50. else if (!os.empty()) {
  51. op = os.back();
  52. if (*s == 0 || get_op_prior(op) >= get_op_prior(*s)) { // 进行运算
  53. int num2 = pop(ns);
  54. int num1 = pop(ns);
  55. op = pop(os);
  56. ans = do_op(num1, num2, op);
  57. push(ns, ans);
  58. //push(os, c);
  59. }
  60. else { // 将运算压入栈中
  61. push(os, *s);
  62. s++;
  63. }
  64. }
  65. else {
  66. push(os, *s);
  67. s++;
  68. }
  69. }
  70. else {
  71. num.push_back(*s);
  72. s++;
  73. }
  74. }
  75. return ns.back();
  76. }
  77. MemoryEx::MemoryEx()
  78. {
  79. }
  80. MemoryEx::~MemoryEx()
  81. {
  82. }
  83. long MemoryEx::WriteData(HWND hwnd, const wstring& address, const wstring& data, LONG size) {
  84. _hwnd = hwnd;
  85. if (!checkaddress(address))
  86. return 0;
  87. vector<uchar> bin;
  88. hex2bins(bin, data,size);
  89. if (_hwnd) {
  90. if (!::IsWindow(hwnd))
  91. return 0;
  92. DWORD pid;
  93. ::GetWindowThreadProcessId(hwnd, &pid);
  94. auto hr = _proc.Attach(pid);
  95. if (hr >= 0) {
  96. size_t addr = str2address(address);
  97. if (addr == 0)return 0;
  98. return mem_write(addr, bin.data(), size);
  99. }
  100. return 0;
  101. }
  102. else {
  103. size_t addr = str2address(address);
  104. if (addr == 0)return 0;
  105. return mem_write(addr,bin.data(), size);
  106. }
  107. }
  108. wstring MemoryEx::ReadData(HWND hwnd, const wstring& address, LONG size) {
  109. _hwnd = hwnd;
  110. if (!checkaddress(address))
  111. return L"";
  112. vector<uchar> bin;
  113. bin.resize(size);
  114. wstring hex;
  115. if (_hwnd) {
  116. if (!::IsWindow(hwnd))
  117. return L"";
  118. DWORD pid;
  119. ::GetWindowThreadProcessId(hwnd, &pid);
  120. auto hr = _proc.Attach(pid);
  121. if (hr >= 0) {
  122. size_t addr = str2address(address);
  123. if (addr == 0)return L"";
  124. mem_read(bin.data(), addr, size);
  125. }
  126. }
  127. else {
  128. size_t addr = str2address(address);
  129. if (addr == 0)return L"";
  130. mem_read(bin.data(), addr, size);
  131. }
  132. bin2hexs(bin, hex);
  133. return hex;
  134. }
  135. bool MemoryEx::mem_read(void* dst, size_t src, size_t size) {
  136. if (_hwnd) {
  137. return _proc.memory().Read(src, size, dst) >= 0;
  138. }
  139. else {
  140. ::memcpy(dst, (void*)src, size);
  141. return true;
  142. }
  143. }
  144. bool MemoryEx::mem_write(size_t dst, void* src, size_t size) {
  145. if (_hwnd) {
  146. return _proc.memory().Write(dst, size, src) >= 0;
  147. }
  148. else {
  149. ::memcpy((void*)dst, src, size);
  150. return true;
  151. }
  152. }
  153. bool MemoryEx::checkaddress(const wstring& address) {
  154. vector<wchar_t> sk;
  155. auto p = address.data();
  156. while (*p) {
  157. if (*p == L'[' || *p == L']') {
  158. if (sk.empty())
  159. sk.push_back(*p);
  160. else if (sk.back() == *p)
  161. sk.push_back(*p);
  162. else
  163. sk.pop_back();
  164. }
  165. p++;
  166. }
  167. return sk.empty();
  168. }
  169. size_t MemoryEx::str2address(const wstring& caddress) {
  170. wstring address = caddress;
  171. if (!checkaddress(address))
  172. return 0;
  173. vector<int> sk;
  174. int idx1 = 0, idx2 = 0;
  175. size_t re = 0;
  176. idx1 = address.find(L'<');
  177. idx2 = address.find(L'>');
  178. if (idx1 != -1 && idx2 != -1 && idx1 < idx2) {
  179. auto mod_name = address.substr(idx1 + 1, idx2 - idx1 - 1);
  180. HMODULE hmod = NULL;
  181. if (_hwnd == 0)
  182. hmod = ::GetModuleHandleW(mod_name.data());
  183. else {
  184. auto mptr = _proc.modules().GetModule(mod_name);
  185. if (mptr)hmod = (HMODULE)mptr->baseAddress;
  186. }
  187. if (hmod == NULL)return 0;
  188. wchar_t buff[128];
  189. wsprintf(buff, L"%X", hmod);
  190. address.replace(idx1, idx2 - idx1 + 1, buff);
  191. }
  192. for (int i = 0; i < address.size();) {
  193. if (address[i] == L'[')push(sk, i);
  194. if (address[i] == L']') {
  195. idx1 = pop(sk);
  196. idx2 = i;
  197. auto sad = address.substr(idx1 + 1, idx2 - idx1 - 1);
  198. size_t src = stringcompute(sad.data());
  199. size_t next;
  200. if (!mem_read(&next, src, sizeof(size_t)) || next == 0)
  201. return 0;
  202. wchar_t buff[128];
  203. wsprintf(buff, L"%X", next);
  204. address.replace(idx1, idx2 - idx1 + 1, buff);
  205. i = idx1;
  206. }
  207. ++i;
  208. }
  209. return stringcompute(address.data());
  210. }
  211. void MemoryEx::hex2bins(vector<uchar>&bin, const wstring& hex,size_t size) {
  212. bin.resize(size);
  213. ZeroMemory(bin.data(), bin.size());
  214. int low = 1;
  215. for (int i = hex.size() - 1; i >= 0; --i) {
  216. bin[size - i / 2-1] |= low & 1 ? hex2bin(hex[i]) : hex2bin(hex[i]) << 4;
  217. low ^= 1;
  218. }
  219. }
  220. void MemoryEx::bin2hexs(const vector<uchar>&bin, wstring& hex) {
  221. //hex.resize(bin.size() * 2);
  222. hex.reserve(bin.size() * 2);
  223. hex.clear();
  224. for (int i = 0; i < bin.size(); ++i) {
  225. int ans = bin2hex(bin[i]);
  226. hex.push_back(ans >> 8);
  227. hex.push_back(ans & 0xff);
  228. }
  229. }