Recent Posts
Recent Comments
Link
11-25 12:52
동글동글 라이프
Win32::Process::Memory 본문
이번에는 프로세스에서 메모리를 읽고 쓸수도 있는 Win32::Process::Memory 에 대해서 알아보자.
이 모듈을 찾게 된 계기는
다른 프로세서에 있는 메모리를 읽어오기 위한 방법이 없을까
해서 cpan에서 찾는 도중 발견~!
Win32::Process::Memory
read and write memory of other windows processWin32-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코드로 덤프, 메모리를 검색, 메모리를 변경까지 해준다.
실행화면
여러가지 함수중 메모리 덤프가 굉장히 유용해 보인다.
사용법을 알았으니 실전으로 테스트를 해보자.
먼저 예전에 조사해두었던 지뢰찾기의 각 블럭의 메모리 주소들을 ollydbg로 확인한다.
0x01005340 부터 0x01005490까지
초급 지뢰찾기의 형태가 출력되어 있는것을 확인 할 수 있다.
이 블럭의 값들이 이해를 돕기 위해 해당 블럭의 값들을 정리해 보았다.
전체 메모리의 양, hex코드로 덤프, 메모리를 검색, 메모리를 변경까지 해준다.
실행화면
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
|
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 |
오픈된 지뢰(게임종료시) |
실제 게임화면과 비슷하게 정규식을 사용하여 메모리 덤프한 파일들을 보기좋게 정리하는 코드를 짜봤다.
항상 생각하지만 정규표현식이 아직 많이 부족해서..
더 좋은 방법으로 문자열을 뽑아내고 싶은 마음이 든다.
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
깔끔하게 지뢰찾기의 블럭들이 정렬되어 출력된다.
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 :- )
'개발자 이야기 > Perl' 카테고리의 다른 글
네이트온 쪽지 자동답장 프로그램 (6) | 2008.12.01 |
---|---|
한글 문자열을 키보드 자판의 영문자로 변환 (4) | 2008.12.01 |
네이버 웹툰 자동댓글 기능 (4) | 2008.11.27 |
perl을 사용한 HTML Parser (1) | 2008.11.23 |
웹용 코드 테스터 (4) | 2008.11.21 |
Comments