Recent Posts
Recent Comments
11-25 12:52
관리 메뉴

동글동글 라이프

Win32::Process::Memory 본문

개발자 이야기/Perl

Win32::Process::Memory

동글동글라이프 2008. 11. 28. 15:52

이번에는 프로세스에서 메모리를 읽고 쓸수도 있는 Win32::Process::Memory 에 대해서 알아보자.

이 모듈을 찾게 된 계기는

다른 프로세서에 있는 메모리를 읽어오기 위한 방법이 없을까 

해서 cpan에서 찾는 도중 발견~!


Win32::Process::Memory

read and write memory of other windows process
Win32-Process-Memory-0.20 - 01 May 2004 - Qing-Jie Zhou 


만든지 꾀 오래 된 모듈이다 

2004년 쯤이니.. 벌써 4년이 훨신 지났다.

기본적인 예제를 한번 실행해 보자.

 # 프로세스를 오픈한다.
  my $proc = Win32::Process::Memory->new({ name=>'cmd.exe' });
  # 디버그
  printf "\nTotal Memory = 0x%X\n", $proc->get_memtotal;
  print "\nMemory block list:\n";
  my %memlist = $proc->get_memlist;
  printf "  %08X -> %08X : Len=0x%X\n", $_, $_+$memlist{$_}, $memlist{$_}
      foreach (sort {$a <=> $b} keys %memlist);
  print "\nContent of 0x10004 -> 0x10103\n";
  print $proc->hexdump(0x10004, 0x100);

  # search a sequence of unsigned int16
  print "\nFind a sequence of unsinged int16:\n";
  my @results = $proc->search_u16(92, 87, 105, 110, 51, 50);
  print $proc->hexdump($_, 0x32)."\n" foreach @results;
  # 값을 읽어와서 바꾼다.
  printf "\n0x%X [unsigned int16] : %d\n", 0x10004, $proc->get_u16(0x10004);
  printf "0x%X [unsigned int32] : %d\n", 0x10004, $proc->get_u32(0x10004);
  #$proc->set_u32(0x10004, 55); # 값을 바꾸는것은 위험하다. 시스템이 손상될 수 있다.

  #프로세스를 종료한다.
  undef $proc;
 
이 모듈은 굉장히 유용한 기능이 많은데..

전체 메모리의 양, hex코드로 덤프, 메모리를 검색, 메모리를 변경까지 해준다.


실행화면

D:\Documents and Settings\honey>perl Memory_test.pl

Total Memory = 0x196C000

Memory block list:
  00010000 -> 00011000 : Len=0x1000
  00020000 -> 00021000 : Len=0x1000
  00030000 -> 00035000 : Len=0x5000
  00040000 -> 00140000 : Len=0x100000
  00140000 -> 00143000 : Len=0x3000
  00150000 -> 00163000 : Len=0x13000
  00250000 -> 00256000 : Len=0x6000
  00260000 -> 00268000 : Len=0x8000
  00270000 -> 00286000 : Len=0x16000
  00290000 -> 002D1000 : Len=0x41000
  002E0000 -> 00321000 : Len=0x41000
  00330000 -> 00336000 : Len=0x6000
  00340000 -> 00381000 : Len=0x41000
  00390000 -> 0039B000 : Len=0xB000
  00450000 -> 00452000 : Len=0x2000
  00460000 -> 00468000 : Len=0x8000
  00470000 -> 00471000 : Len=0x1000
  00480000 -> 00481000 : Len=0x1000
  00490000 -> 00492000 : Len=0x2000
  004A0000 -> 004A4000 : Len=0x4000
  004B0000 -> 004B2000 : Len=0x2000
  004C0000 -> 004C8000 : Len=0x8000
  004D0000 -> 004D4000 : Len=0x4000
  004E0000 -> 004E3000 : Len=0x3000
  004F0000 -> 004F3000 : Len=0x3000
  00530000 -> 00633000 : Len=0x103000
  00640000 -> 007B3000 : Len=0x173000
  00940000 -> 00941000 : Len=0x1000
  009C0000 -> 009C1000 : Len=0x1000
  009D0000 -> 009DE000 : Len=0xE000
  009E0000 -> 009E1000 : Len=0x1000
  00A60000 -> 00A62000 : Len=0x2000
  4AD00000 -> 4AD01000 : Len=0x1000
  4AD01000 -> 4AD21000 : Len=0x20000
  4AD21000 -> 4AD22000 : Len=0x1000
  4AD22000 -> 4AD25000 : Len=0x3000
  4AD25000 -> 4AD26000 : Len=0x1000
  4AD26000 -> 4AD29000 : Len=0x3000
  4AD29000 -> 4AD2C000 : Len=0x3000
  4AD2C000 -> 4AD2F000 : Len=0x3000
  4AD2F000 -> 4AD30000 : Len=0x1000
  4AD30000 -> 4AD33000 : Len=0x3000
  4AD33000 -> 4AD39000 : Len=0x6000
  4AD39000 -> 4AD3C000 : Len=0x3000
  4AD3C000 -> 4AD3D000 : Len=0x1000
  4AD3D000 -> 4AD3E000 : Len=0x1000
  4AD3E000 -> 4AD78000 : Len=0x3A000
  5A480000 -> 5A481000 : Len=0x1000
  5A481000 -> 5A4B1000 : Len=0x30000
  5A4B1000 -> 5A4B2000 : Len=0x1000
  5A4B2000 -> 5A4B8000 : Len=0x6000
  5C2E0000 -> 5C2E1000 : Len=0x1000
  5C2E1000 -> 5C2EF000 : Len=0xE000
  5C2EF000 -> 5C2F2000 : Len=0x3000
  5C2F2000 -> 5C303000 : Len=0x11000
  5C303000 -> 5C306000 : Len=0x3000
  5C820000 -> 5C821000 : Len=0x1000
  5C821000 -> 5C892000 : Len=0x71000
  5C892000 -> 5C895000 : Len=0x3000
  5C895000 -> 5C8BA000 : Len=0x25000
  62340000 -> 62341000 : Len=0x1000
  62341000 -> 62346000 : Len=0x5000
  62346000 -> 62347000 : Len=0x1000
  62347000 -> 62349000 : Len=0x2000
  6FD60000 -> 6FD61000 : Len=0x1000
  6FD61000 -> 6FD93000 : Len=0x32000
  6FD93000 -> 6FD94000 : Len=0x1000
  6FD94000 -> 6FD98000 : Len=0x4000
  6FD98000 -> 6FD9C000 : Len=0x4000
  6FD9C000 -> 6FF2A000 : Len=0x18E000
  73F80000 -> 73F81000 : Len=0x1000
  73F81000 -> 73FC5000 : Len=0x44000
  73FC5000 -> 73FCF000 : Len=0xA000
  73FCF000 -> 73FD1000 : Len=0x2000
  73FD1000 -> 73FD4000 : Len=0x3000
  73FD4000 -> 73FD5000 : Len=0x1000
  73FD5000 -> 73FEB000 : Len=0x16000
  762E0000 -> 762E1000 : Len=0x1000
  762E1000 -> 762F6000 : Len=0x15000
  762F6000 -> 762F7000 : Len=0x1000
  762F7000 -> 762FD000 : Len=0x6000
  76970000 -> 76971000 : Len=0x1000
  76971000 -> 76A96000 : Len=0x125000
  76A96000 -> 76A97000 : Len=0x1000
  76A97000 -> 76A9D000 : Len=0x6000
  76A9D000 -> 76AAD000 : Len=0x10000
  76AF0000 -> 76AF1000 : Len=0x1000
  76AF1000 -> 76B10000 : Len=0x1F000
  76B10000 -> 76B11000 : Len=0x1000
  76B11000 -> 76B12000 : Len=0x1000
  76B12000 -> 76B1B000 : Len=0x9000
  76D90000 -> 76D91000 : Len=0x1000
  76D91000 -> 76DAE000 : Len=0x1D000
  76DAE000 -> 76DAF000 : Len=0x1000
  76DAF000 -> 76DB2000 : Len=0x3000
  770D0000 -> 770D1000 : Len=0x1000
  770D1000 -> 77151000 : Len=0x80000
  77151000 -> 77152000 : Len=0x1000
  77152000 -> 77154000 : Len=0x2000
  77154000 -> 7715B000 : Len=0x7000
  77160000 -> 77161000 : Len=0x1000
  77161000 -> 771F2000 : Len=0x91000
  771F2000 -> 771F3000 : Len=0x1000
  771F3000 -> 77263000 : Len=0x70000
  77B90000 -> 77B91000 : Len=0x1000
  77B91000 -> 77BA1000 : Len=0x10000
  77BA1000 -> 77BA2000 : Len=0x1000
  77BA2000 -> 77BA5000 : Len=0x3000
  77BB0000 -> 77BB1000 : Len=0x1000
  77BB1000 -> 77BB5000 : Len=0x4000
  77BB5000 -> 77BB6000 : Len=0x1000
  77BB6000 -> 77BB8000 : Len=0x2000
  77BC0000 -> 77BC1000 : Len=0x1000
  77BC1000 -> 77C0D000 : Len=0x4C000
  77C0D000 -> 77C0F000 : Len=0x2000
  77C0F000 -> 77C10000 : Len=0x1000
  77C10000 -> 77C11000 : Len=0x1000
  77C11000 -> 77C14000 : Len=0x3000
  77C14000 -> 77C18000 : Len=0x4000
  77CF0000 -> 77CF1000 : Len=0x1000
  77CF1000 -> 77D51000 : Len=0x60000
  77D51000 -> 77D52000 : Len=0x1000
  77D52000 -> 77D53000 : Len=0x1000
  77D53000 -> 77D80000 : Len=0x2D000
  77D80000 -> 77D81000 : Len=0x1000
  77D81000 -> 77E0B000 : Len=0x8A000
  77E0B000 -> 77E0C000 : Len=0x1000
  77E0C000 -> 77E12000 : Len=0x6000
  77E20000 -> 77E21000 : Len=0x1000
  77E21000 -> 77E64000 : Len=0x43000
  77E64000 -> 77E66000 : Len=0x2000
  77E66000 -> 77E69000 : Len=0x3000
  77E70000 -> 77E71000 : Len=0x1000
  77E71000 -> 77EDD000 : Len=0x6C000
  77EDD000 -> 77EDE000 : Len=0x1000
  77EDE000 -> 77EE6000 : Len=0x8000
  77EF0000 -> 77EF1000 : Len=0x1000
  77EF1000 -> 77EFE000 : Len=0xD000
  77EFE000 -> 77EFF000 : Len=0x1000
  77EFF000 -> 77F01000 : Len=0x2000
  77F50000 -> 77F51000 : Len=0x1000
  77F51000 -> 77FC6000 : Len=0x75000
  77FC6000 -> 77FC7000 : Len=0x1000
  77FC7000 -> 77FCB000 : Len=0x4000
  77FCB000 -> 77FF8000 : Len=0x2D000
  7C800000 -> 7C801000 : Len=0x1000
  7C801000 -> 7C885000 : Len=0x84000
  7C885000 -> 7C888000 : Len=0x3000
  7C888000 -> 7C88A000 : Len=0x2000
  7C88A000 -> 7C930000 : Len=0xA6000
  7C930000 -> 7C931000 : Len=0x1000
  7C931000 -> 7C9AB000 : Len=0x7A000
  7C9AB000 -> 7C9AE000 : Len=0x3000
  7C9AE000 -> 7C9AF000 : Len=0x1000
  7C9AF000 -> 7C9B0000 : Len=0x1000
  7C9B0000 -> 7C9CB000 : Len=0x1B000
  7D5A0000 -> 7D5A1000 : Len=0x1000
  7D5A1000 -> 7D79F000 : Len=0x1FE000
  7D79F000 -> 7D7AF000 : Len=0x10000
  7D7AF000 -> 7D7B5000 : Len=0x6000
  7D7B5000 -> 7D7BC000 : Len=0x7000
  7D7BC000 -> 7DD9D000 : Len=0x5E1000
  7E8C0000 -> 7E8C1000 : Len=0x1000
  7E8C1000 -> 7E961000 : Len=0xA0000
  7E961000 -> 7E963000 : Len=0x2000
  7E963000 -> 7E971000 : Len=0xE000
  7F6F0000 -> 7F6F7000 : Len=0x7000
  7FFA0000 -> 7FFD3000 : Len=0x33000
  7FFD4000 -> 7FFD5000 : Len=0x1000
  7FFDF000 -> 7FFE0000 : Len=0x1000
  7FFE0000 -> 7FFE1000 : Len=0x1000

Content of 0x10004 -> 0x10103
00010000 :             3A 00 3D 00 3A 00 3A 00 5C 00 00 00 :     :.=.:.:.\...
00010010 : 3D 00 44 00 3A 00 3D 00 44 00 3A 00 5C 00 44 00 : =.D.:.=.D.:.\.D.
00010020 : 6F 00 63 00 75 00 6D 00 65 00 6E 00 74 00 73 00 : o.c.u.m.e.n.t.s.
00010030 : 20 00 61 00 6E 00 64 00 20 00 53 00 65 00 74 00 :  .a.n.d. .S.e.t.
00010040 : 74 00 69 00 6E 00 67 00 73 00 5C 00 68 00 6F 00 : t.i.n.g.s.\.h.o.
00010050 : 6E 00 65 00 79 00 00 00 3D 00 45 00 78 00 69 00 : n.e.y...=.E.x.i.
00010060 : 74 00 43 00 6F 00 64 00 65 00 3D 00 30 00 30 00 : t.C.o.d.e.=.0.0.
00010070 : 30 00 30 00 30 00 30 00 30 00 30 00 00 00 41 00 : 0.0.0.0.0.0...A.
00010080 : 4C 00 4C 00 55 00 53 00 45 00 52 00 53 00 50 00 : L.L.U.S.E.R.S.P.
00010090 : 52 00 4F 00 46 00 49 00 4C 00 45 00 3D 00 44 00 : R.O.F.I.L.E.=.D.
000100A0 : 3A 00 5C 00 44 00 6F 00 63 00 75 00 6D 00 65 00 : :.\.D.o.c.u.m.e.
000100B0 : 6E 00 74 00 73 00 20 00 61 00 6E 00 64 00 20 00 : n.t.s. .a.n.d. .
000100C0 : 53 00 65 00 74 00 74 00 69 00 6E 00 67 00 73 00 : S.e.t.t.i.n.g.s.
000100D0 : 5C 00 41 00 6C 00 6C 00 20 00 55 00 73 00 65 00 : \.A.l.l. .U.s.e.
000100E0 : 72 00 73 00 00 00 41 00 50 00 50 00 44 00 41 00 : r.s...A.P.P.D.A.
000100F0 : 54 00 41 00 3D 00 44 00 3A 00 5C 00 44 00 6F 00 : T.A.=.D.:.\.D.o.
00010100 : 63 00 75 00                                     : c.u.

Find a sequence of unsinged int16:
0x10004 [unsigned int32] : 3997754


여러가지 함수중 메모리 덤프가 굉장히 유용해 보인다.


사용법을 알았으니 실전으로 테스트를 해보자.


먼저 예전에 조사해두었던 지뢰찾기의  각 블럭의 메모리 주소들을 ollydbg로 확인한다.




0x01005340 부터 0x01005490까지

초급 지뢰찾기의 형태가 출력되어 있는것을 확인 할 수 있다.


이 블럭의 값들이 이해를 돕기 위해 해당 블럭의 값들을 정리해 보았다.

 

16진수

블록의 용도

0x10

테두리

0x0F

오픈되지 않은 블록

0x0E

체크한 지뢰

0x0D

물음표

0x40~0x48

주변의 지뢰갯수

0x8F

오픈되지 않은 지뢰

0xCC

빨간색 지뢰(지뢰가 터졌을 때)

0x8A

오픈된 지뢰(게임종료시)




실제 게임화면과 비슷하게 정규식을 사용하여 메모리 덤프한 파일들을 보기좋게 정리하는 코드를 짜봤다.

항상 생각하지만 정규표현식이 아직 많이 부족해서..

더 좋은 방법으로 문자열을 뽑아내고 싶은 마음이 든다.




1
2
3
4
5
6
7
8
9
10
11
use Win32::Process::Memory;

my $proc = Win32::Process::Memory->new({ name=>'winmine.exe' });
printf "\nTotal Memory = 0x%X\n", $proc->get_memtotal;
print "\nContent of 0x01005340 -> 0x01005490\n";
my $block = $proc->hexdump(0x01005340, 0x150);
my @blocks = $block =~ m/10\s.*\s10/g;
$block = join "\n",@blocks;
$block =~ s/10//g;
print "$block";
undef $proc;


http://codepad.org/nviziVV4


깔끔하게 지뢰찾기의 블럭들이 정렬되어 출력된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
D:\Documents and Settings\honey>perl winmine.pl

Total Memory = 0x1B64000

Content of 0x01005340 -> 0x01005490

 0F 0F 0F 8F 0F 0F 0F 0F 0F
 0F 0F 0F 0F 0F 0F 0F 0F 0F
 0F 0F 0F 0F 8F 8F 0F 0F 0F
 0F 0F 0F 0F 0F 0F 0F 0F 0F
 0F 0F 0F 0F 0F 0F 0F 0F 0F
 0F 0F 0F 0F 0F 8F 0F 0F 0F
 8F 0F 8F 0F 0F 0F 0F 0F 0F
 0F 8F 0F 0F 8F 0F 0F 0F 0F
 0F 0F 8F 0F 0F 0F 8F 0F 0F


이제 게임으로 !!




실제로 출력화면을 보고 지뢰찾기를 한 것인데... 시간은 신경쓰지말자;;


보면서 하니깐 더 안되는... OTL...

위의 출력된 지뢰위치와 그림파일의 지뢰위치가 동일한 것을 확인 할 수 있다.



사용자정의로 말도안되는 지뢰찾기맵을 만들더라도 가볍게 클리어 해주자...





Win32::Process::Memory는 메모리를 write도 가능하기 때문에

위의 작성한 코드를 조금만 수정하여..

모든 블럭의 값을 수정하여 지뢰로 만들어 보았다.




원래는 이런 구성은 만들어 질 수 없으며...

생각만해도 아찔한 영상이다;;



전에 소개한 Win32::GuiTest 모듈을 사용하여

MineFinder를 구현해 보았다.

자동으로 Mine을 찾아서 게임을 클리어 해주는 프로그램인데...



지뢰찾기를 실행시킨 뒤

위의 코드와 같이 정규식으로 뽑아낸 값을 통해서 비교를 한 뒤

해당 위치가 지뢰일 때는 우클릭 그 위외에는 모두 좌클릭을 해 주었다.


머릿속으로 생각한 뒤 구현하려니 좀 버벅되긴 했지만... 

이론으로 충분히 가능했기 때문에 구현하는데 그리 오래 걸리진 않았다.


초급으로 만드는 코드를 처음에 실행한다 ㅡ_ㅡ;

반 강제적으로 초급만 되도록... 설정하였다 ( 중급 고급이 다 되게 하는것이 조금 빡세서...)






대부분 3초안에 클리어 할 수 있으며 빠르면 1초안에 클리어도 가능하다.







Good Job  :- )


Comments