paulohr

Memory Scanner converted to Delphi

Apr 3rd, 2012
21
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 10.13 KB | None | 0 0
  1. //Declarations
  2. type
  3.  PMEMBLOCK = ^MEMBLOCK;
  4.  MEMBLOCK = packed record
  5.   hProc: THandle;
  6.   addr: array of byte;
  7.   size: integer;
  8.   buffer: array of byte;
  9.   searchmask: array of byte;
  10.   matches: integer;
  11.   data_size: integer;
  12.   next: array of PMEMBLOCK;
  13. end;
  14.  
  15. type
  16.  SEARCH_CONDITION = (COND_UNCONDITIONAL, COND_EQUALS, COND_INCREASED, COND_DECREASED);
  17.  
  18. const
  19.  WRITABLE = (PAGE_READWRITE and PAGE_WRITECOPY and PAGE_EXECUTE_READWRITE and PAGE_EXECUTE_WRITECOPY);
  20.  
  21. function Is_In_Search(mb: PMEMBLOCK; offset: cardinal): Boolean;
  22. begin
  23.   Result := 0 <> (mb.searchmask[offset div 8] and (1 shl (offset mod 8)));
  24. end;
  25.  
  26. procedure Remove_From_Search(mb: PMEMBLOCK; offset: cardinal);
  27. begin
  28.   mb.searchmask[offset div 8] := mb.searchmask[offset div 8] and not (1 shl (offset mod 8));
  29. end;
  30.  
  31.  
  32. function create_memblock(hProc: THandle; meminfo: MEMORY_BASIC_INFORMATION; data_size: integer): PMemblock;
  33. var
  34.  mb: PMemblock;
  35.  x:integer;
  36. begin
  37. x:= round(meminfo.RegionSize/8);
  38.  mb:= malloc(sizeof(MEMBLOCK));
  39.  if mb<>ptr(0) then begin
  40.   mb.hProc := hProc;
  41.   mb.addr := meminfo.BaseAddress;
  42.   mb.size := meminfo.RegionSize;
  43.   mb.buffer := malloc(meminfo.RegionSize);
  44.   mb.searchmask := malloc(x);
  45.   memset(mb.searchmask, $ff, x);
  46.   mb.matches := meminfo.RegionSize;  
  47.   mb.next := NULL;
  48.   mb.data_size := data_size;
  49.  end;
  50.  result := mb;
  51. end;
  52.  
  53. procedure free_memblock(mb:pmemblock);
  54. begin
  55.  if mb<>ptr(0) then begin
  56.   if mb.buffer<>ptr(0) then free(mb.buffer);
  57.   if mb.searchmask<>ptr(0) then free(mb.searchmask);
  58.   mb:=nil;
  59.  end;
  60. end;
  61.  
  62. procedure update_memblock(mb:pmemblock; condition:SEARCH_CONDITION; val:cardinal);
  63. var
  64.  tempbuf: array[0..(128*1024)-1] of Byte;
  65.  bytes_left: cardinal;
  66.  total_read: cardinal;
  67.  bytes_to_read: cardinal;
  68.  bytes_read: cardinal;
  69.  offset: cardinal;
  70.  x, z:integer;
  71.  is_match: boolean;
  72.  temp_val, prev_val: cardinal;
  73. begin
  74.  if mb.matches > 0 then begin
  75.   bytes_left := mb.size;
  76.   total_read := 0;
  77.   mb.matches := 0;
  78.   while (bytes_left<>0) do begin
  79.    if bytes_left > sizeof(tempbuf) then bytes_to_read := sizeof(tempbuf) else bytes_to_read := bytes_left;
  80.    //TO USE IN DLL: tempbuf[0] :=  PBYTE(dword(mb.addr)+total_read)^; // bytes_to_read = 1bytes  {PRECISA CRIAR IF PROS OUTROS TIPOS}
  81.    ReadProcessMemory(mb.hProc, pointer(dword(mb.addr)+total_read), @tempbuf, bytes_to_read, dword(bytes_to_read));
  82.  
  83.    if bytes_read <> bytes_to_read then break;
  84.  
  85.    if condition = COND_UNCONDITIONAL then begin
  86.     x:= round(total_read/8);  
  87.     z:= round(bytes_read/8);
  88.     memset (pointer(dword(mb.searchmask) + x), $ff, z);
  89.     mb.matches :=+ bytes_read;
  90.    end
  91.    else
  92.    begin
  93.      offset:=0;
  94.      while (offset < bytes_read) do
  95.      begin
  96.  
  97.        if IS_IN_SEARCH(mb, (total_read+offset)) then begin
  98.         is_match:=false;
  99.         prev_val := 0;
  100.        end;
  101.  
  102.        case mb.data_size of
  103.        1: begin
  104.             temp_val := tempbuf[offset];
  105.             prev_val := PBYTE(mb.buffer[total_read+offset])^;
  106.             break;
  107.           end;    
  108.        2: begin  
  109.             temp_val := PWORD(tempbuf[offset])^;
  110.             prev_val := PWORD(mb.buffer[total_read+offset])^;
  111.             break;
  112.           end;
  113.        4: begin  
  114.             temp_val := PDWORD(tempbuf[offset])^;
  115.             prev_val := PDWORD(mb.buffer[total_read+offset])^;
  116.             break;
  117.           end;
  118.        end;
  119.  
  120.        case condition of
  121.           COND_EQUALS: begin
  122.                         is_match := temp_val = val;
  123.                         break;
  124.                        end;
  125.        COND_INCREASED: begin
  126.                         is_match := (temp_val > prev_val);
  127.                         break;
  128.                        end;
  129.        COND_DECREASED: begin
  130.                         is_match := (temp_val < prev_val);
  131.                         break;
  132.                        end;
  133.        end;
  134.  
  135.        if (is_match) then
  136.         inc(mb.matches)
  137.        else
  138.         REMOVE_FROM_SEARCH(mb,(total_read+offset));
  139.  
  140.         bytes_left :=- bytes_read;
  141.         total_read :=+ bytes_read;
  142.  
  143.       Inc(offset, mb.data_size);
  144.      end;
  145.    end;
  146.  
  147.     memcpy(pointer(dword(mb.buffer) + total_read), @tempbuf, bytes_read);
  148.  
  149.   end;
  150.   mb.size := total_read;
  151.  end;
  152. end;
  153.  
  154. function create_scan(pid: cardinal; data_size: integer):PMEMBLOCK;
  155. var
  156.  mb_list: PMEMBLOCK;
  157.  meminfo: MEMORY_BASIC_INFORMATION;
  158.  addr: PBYTE;
  159.  hProc: THandle;
  160.  mb: PMEMBLOCK;
  161. begin
  162.  mb_list:=nil;
  163.  addr:=nil;
  164.  hProc := OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
  165.  if hProc<>0 then begin
  166.   while 1<>0 do begin
  167.     if VirtualQueryEx(hProc, pointer(addr), meminfo, sizeof(meminfo))=0 then break;
  168.  
  169.      if ((meminfo.State = MEM_COMMIT) and (meminfo.Protect = WRITABLE )) then begin
  170.       mb := create_memblock(hProc, meminfo, data_size);
  171.       if mb<>ptr(0) then begin
  172.             mb.next := @mb_list;
  173.             mb_list := mb;
  174.       end;
  175.      end;
  176.      addr := pbyte(dword(meminfo.BaseAddress) + dword(meminfo.RegionSize));
  177.   end;
  178.  end;
  179.  result := mb_list;
  180. end;
  181.  
  182.  
  183. procedure free_scan(mb_list: PMEMBLOCK);
  184. var
  185.  mb: PMEMBLOCK;
  186. begin
  187.      CloseHandle(mb_list.hProc);
  188.      
  189.      while mb_list<>ptr(0) do
  190.       begin
  191.            mb := mb_list;
  192.            mb_list := @mb_list.next;
  193.            free_memblock(mb);
  194.      end;
  195. end;
  196.  
  197. procedure update_scan(mb_list: PMEMBLOCK; condition: SEARCH_CONDITION; val: cardinal);
  198. var
  199.  mb: PMEMBLOCK;
  200. begin
  201.      mb := mb_list;
  202.      while mb<>ptr(0) do
  203.      begin
  204.            update_memblock(mb, condition, val);
  205.            mb := @mb.next;
  206.      end;
  207. end;
  208.  
  209.  
  210. procedure dump_scan_info(mb_list: PMEMBLOCK);
  211. var
  212.  mb: PMEMBLOCK;
  213.  i: integer;
  214. begin
  215.      mb := mb_list;
  216.      while mb<>ptr(0) do
  217.      begin
  218.            writeln(Format('0x%08x %d',[mb.addr, mb.size]));
  219.  
  220.            for i := 0 to mb.size do
  221.            begin
  222.                writeln(Format('%02x',[mb.buffer[i]]));
  223.            end;
  224.            writeln('');
  225.  
  226.            mb := @mb.next;
  227.      end;
  228. end;
  229.  
  230. procedure poke(hProc:THANDLE; data_size: integer; addr: cardinal; val: cardinal);
  231. var
  232.  write: cardinal;
  233. begin
  234.  if not ReadProcessMemory(hProc, pointer(addr), @val, data_size, write) then
  235.   writeln('poke failed');
  236. end;
  237.  
  238. function peek(hProc: THandle; data_size: integer; addr: cardinal):cardinal;
  239. var
  240.  val: cardinal;
  241.  write: cardinal;
  242. begin
  243.  val := 0;
  244.  
  245.  if not ReadProcessMemory(hProc, pointer(addr), @val, data_size, write) then
  246.    writeln('poke failed');
  247.  
  248.      
  249.  result := val;
  250. end;
  251.  
  252. procedure print_matches(mb_list: PMEMBLOCK);
  253. var
  254.  offset: cardinal;
  255.  mb: PMEMBLOCK;
  256.  val: cardinal;
  257. begin
  258.      mb := mb_list;
  259.  
  260.      while mb<>ptr(0) do
  261.      begin
  262.            offset:=0;
  263.            while (offset<mb.size) do
  264.            begin
  265.  
  266.                if IS_IN_SEARCH(mb, offset) then begin
  267.                   val := peek(mb.hProc, mb.data_size, dword(dword(mb.addr) + offset));
  268.                   writeln(format('0x%08x: 0x%08x (%d)',[dword(dword(mb.addr) + offset), val]));
  269.                end;
  270.  
  271.            Inc(offset, mb.data_size);
  272.            end;
  273.            
  274.            mb := @mb.next;
  275.      end;
  276. end;
  277.  
  278. function get_match_count(mb_list: PMEMBLOCK): integer;
  279. var
  280.  mb: PMEMBLOCK;
  281.  count: integer;
  282. begin
  283.     mb := mb_list;
  284.     count := 0;
  285.    
  286.     while mb<>ptr(0) do
  287.     begin
  288.           count :=+ mb.matches;
  289.           mb := @mb.next;
  290.     end;
  291.  
  292.     Result := count;
  293. end;
  294.  
  295. function ui_new_scan: PMEMBLOCK;
  296. var
  297.  scan: PMEMBLOCK;
  298.  pid: dword;
  299.  data_size: integer;
  300.  start_val: cardinal;
  301.  start_cond: SEARCH_CONDITION;
  302.  s: array [0..19] of char;
  303. begin
  304.  scan := nil;
  305.  
  306.  while 1<>0 do
  307.  begin
  308.   writeln('Digite o pid: ');
  309.   readln(s);
  310.   pid := strtoint(s);
  311.   writeln('Enter the data size: ');
  312.   readln(s);
  313.   data_size := strtoint(s);
  314.   writeln('Enter the start value, or ''u'' for unknown:  ');
  315.   readln(s);
  316.   if s[0] = 'u' then begin
  317.    start_cond := COND_UNCONDITIONAL;
  318.    start_val := 0;
  319.   end else
  320.   begin
  321.    start_cond := COND_EQUALS;
  322.    start_val := strtoint(s);
  323.   end;
  324.    scan := create_scan (pid, data_size);
  325.    if scan<>ptr(0) then break;
  326.    writeln('Invalid scan');
  327.  end;
  328.    update_scan(scan, start_cond, start_val);
  329.    writeln(Format('%d matches found', [get_match_count(scan)]));
  330.    
  331.    Result := scan;
  332. end;
  333.  
  334. procedure ui_poke(hProc: THandle; data_size: integer);
  335. var
  336.  addr: cardinal;
  337.  val: cardinal;
  338.  s: array [0..19] of char;
  339. begin        
  340.   writeln('Enter the address: ');
  341.   readln(s);
  342.   addr := strtoint(s);
  343.   writeln('Enter the value: ');
  344.   readln(s);
  345.   val := strtoint(s);
  346.   writeln('');
  347.   poke(hProc, data_size, addr, val);
  348. end;
  349.  
  350. function CaseOfString(s: string; a: array of string): Integer;
  351. begin
  352.   Result := 0;
  353.   while (Result < Length(a)) and (a[Result] <> s) do
  354.     Inc(Result);
  355.   if a[Result] <> s then
  356.     Result := -1;
  357. end;
  358.  
  359. procedure ui_run_scan;
  360. var
  361.  val: cardinal;
  362.  s: array [0..19] of char;
  363.  scan: PMEMBLOCK;
  364. begin
  365.  scan := ui_new_scan();
  366.  
  367.  while 1<>0 do
  368.  begin
  369.    writeln('Enter the next value or');
  370.    writeln('[i] increased');
  371.    writeln('[d] decreased');
  372.    writeln('[m] print matches');
  373.    writeln('[p] poke address');
  374.    writeln('[n] new scan');
  375.    writeln('[q] quit');
  376.  
  377.    readln(s);
  378.  
  379.    if s[0] = 'i' then begin
  380.     update_scan(scan, COND_INCREASED, 0);
  381.     writeln(Format(' %d matches found', [get_match_count(scan)]));
  382.     break;
  383.    end;  
  384.  
  385.    if s[0] = 'd' then begin
  386.     update_scan(scan, COND_DECREASED, 0);
  387.     writeln(Format(' %d matches found', [get_match_count(scan)]));
  388.     break;
  389.    end;
  390.  
  391.    if s[0] = 'm' then begin
  392.     print_matches(scan);
  393.     break;
  394.    end;
  395.  
  396.    if s[0] = 'p' then begin
  397.     ui_poke (scan.hProc, scan.data_size);
  398.     break;
  399.    end;
  400.  
  401.    if s[0] = 'n' then begin
  402.      free_scan(scan);
  403.      scan := ui_new_scan();
  404.     break;
  405.    end;
  406.  
  407.    if s[0] = 'q' then begin
  408.     free_scan(scan);
  409.     exit;
  410.    end;
  411.  
  412.    if s[0] = 'p' then begin
  413.     ui_poke (scan.hProc, scan.data_size);
  414.     break;
  415.    end;
  416.  
  417.    if (s[0]<>'i') and (s[0]<>'d') and (s[0]<>'m') and (s[0]<>'p') and (s[0]<>'n') and (s[0]<>'q') then begin
  418.      val := strtoint(s);
  419.      update_scan(scan, COND_EQUALS, val);
  420.      writeln(Format('%d matches found', [get_match_count(scan)]));
  421.      break;
  422.    end;
  423.  end;
  424. end;
  425.  
  426. procedure Main;
  427. begin
  428.  ui_run_scan();
  429. end;
Advertisement
Add Comment
Please, Sign In to add comment