2009년 1월 30일 금요일

AutoIt에서 Registry 다루기....

레지스트리 정보를 이루는 요소로는 4가지가 있습니다.
Key와 ValueName, Type, Value.
레지스트리 백업 파일에는 이 정보들이 들어있죠..

[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Safer\CodeIdentifiers]
"ClassName"="ipsecFilter"
"TransparentEnabled"=dword:00000001
"ItemData"=hex:38,6b,08,5f,84,ec,f6,69,d3,6b,95,6a,22,c0,1e,80
"LastModified"=hex(b):40,b2,40,dc,19,a2,c2,01
"ItemData"=hex(2):25,00,48,00,4b,00,45,00,59,00,5f,00,43,00,55,00,52,00,52,00,\
  ........
"ExecutableTypes"=hex(7):41,00,44,00,45,00,00,00,41,00,44,00,50,00,00,00,42,00,\
  .......

위 레지스트리 내용을 예로 삼고자 합니다.
대괄호([])로 싸여 있는 내용이 Key에 해당하는 내용입니다.
탐색기에서 보자면 폴더부분에 해당하겠군요..

그 아래에 레지스트리의 나머지 정보들이 포함되어 있습니다.
모두들 xxx=yyy의 형태를 취하고 있는데요..
등호 앞의 부분이 ValueName, 뒷 부분에 Type과 Value 정보가 들어있습니다.
문자열(REG_ZS)의 경우에는 간단하게 구분이 가능합니다.
우선 우리가 값을 직접 읽을 수 있다는 것과 등호 앞뒤가 모두 큰따옴표("")로 묶여 있다는 것이죠..
문자열 이외의 데이터들을 보면 xxx=yyy:zzz 형식으로 이루어져 있습니다.
ValueName=Type:Value 형태이죠..
이제 타입 종류를 알아보도록 하겠습니다.
문자열값(REG_SZ)
이진값(REG_BINARY)
DWORD값(REG_DWORD)
QWORD값(REG_QWORD)
다중 문자열값(REG_MULTI_SZ)
확장 가능 다중 문자열값(REG_EXPAND_SZ)
이외에도 다양하지만 많이 쓰이는 값들 위주로 해보죠...

앞서도 이야기 했지만 문자열은 레지 파일을 열어보기만 해도 찾을 수 있습니다.
나머지 값들이 문제죠 ^^:
나머지 값들은 대부분 저장될 때 Value를 이진형태로 저장합니다.
DWORD 만이 hex값으로 저장하죠..
dword:00000001과 같은 형태로 존재 합니다. DWORD타입 00000001 값이 됩니다.
실제 DWORD를 RegWrite()함수를 통해 보내어 줄 때

RegWrite("HKLM\Software\Test", "TestName", 'REG_DWORD', '00000001')

로  입력한다면 전혀 다른 엉뚱한 값이 들어가게 됩니다.
Hex값을 10진수로 변경해 넣어줘야 하죠..

RegWrite("HKLM\Software\Test", "TestName", 'REG_DWORD', Dec('00000001'))

Dec()함수를 통해 Hex값을 10진수로 변경했습니다.  이제 값이 정상으로 나타날 것입니다.

다른 타입들을 보면 타입들이 hex:, hex(b), hex(2), hex(7)등으로 나타나있습니다.
이를 우리가 아는 타입이름으로 변경해 보면..
hex  = 이진값(REG_BINARY)
hex(b) = QWORD값(REG_QWORD)
hex(2) = 확장 가능 다중 문자열값(REG_EXPAND_SZ)
hex(7) = 다중 문자열값(REG_MULTI_SZ)
이 됩니다.
이들의 값은 모두 바이너리 코드로 저장되어 있으며 여러줄에 걸쳐 등록되어 있습니다.
그중 가장 쉽게 변환할 수 있는 값은 이진값입니다.
공통적으로 먼저 각 바이너리 코드 사이의 쉼표(,)를 제거하고 역슬래쉬(\)를 없앤 후 한줄로 합쳐줍니다.
이후 이진값은 Binary()함수를 이용해 동일한 값으로 만들어 전달할 수 있습니다.

RegWrite("HKLM\Software\Test", "TestName", 'REG_BINARY',
Binary
('0x'&'386b085f84ecf669d36b956a22c01e80'))

바이너리 값으로 변경할 때 주의해야 할 것이 앞에 '0x'를 붙여 주어야 한다는 것이죠. 이게 없으면 값이 변합니다.

MsgBox(0, '바이너리 값 확인', Binary('386b085f84ecf669d36b956a22c01e80') &
@CRLF
& Binary('0x'&'386b085f84ecf669d36b956a22c01e80'))


위 명령줄을 통해 값이 어떻게 변하는지 확인해 보세요 ^^

가장 데이터 읽기가 어려운 것이 다중 문자열값(REG_MULTI_SZ)과 확장 가능 다중 문자열값(REG_EXPAND_SZ)입니다.
이 두 타입을 읽어 들일때엔 BinaryToString()함수를 이용합니다만,
그냥 읽어 들이기만 해서는 전체 데이터가 나오지를 않습니다.
줄바꿈 때문에 첫번째 열 데이터만 나타나죠..

자.. 아래는 REG_MULTI_SZ 타입의 값입니다.(이 이진값은 UTF16LittleEndian입니다.)
53004f004600540057004100520045005c0050006f006c00690063006900650073005c004d006900630072006f007300
6f00660074005c00570069006e0064006f00770073005c00490050005300650063005c0050006f006c00690063007900
5c004c006f00630061006c005c00690070007300650063004e00460041007b0034003500640064003900630032003200
2d0062006100380032002d0034003100310032002d0061006400380039002d0038003300610031006100330062006100
34006300310030007d00000053004f004600540057004100520045005c0050006f006c00690063006900650073005c00
4d006900630072006f0073006f00660074005c00570069006e0064006f00770073005c00490050005300650063005c00
50006f006c006900630079005c004c006f00630061006c005c00690070007300650063004e00460041007b0035003700
3700660066003000650065002d0066003900350032002d0034003700390034002d0039006600340062002d00370032
0062003400330039006100640065003100620038007d0000000000

BinaryToString()함수를 통해 읽어 볼까요..
MsgBox(0, '이진값을 문자열로 변경', BinaryToString('0x'&'53004f004600540057004100520045005c0050006f006c0069006
3006900650073005c004d006900630072006f0073006f00660074005c00570069006e00640
06f00770073005c00490050005300650063005c0050006f006c006900630079005c004c006
f00630061006c005c00690070007300650063004e00460041007b003400350064006400390
06300320032002d0062006100380032002d0034003100310032002d0061006400380039002
d003800330061003100610033006200610034006300310030007d00000053004f004600540
057004100520045005c0050006f006c00690063006900650073005c004d006900630072006
f0073006f00660074005c00570069006e0064006f00770073005c004900500053006500630
05c0050006f006c006900630079005c004c006f00630061006c005c0069007000730065006
3004e00460041007b00350037003700660066003000650065002d0066003900350032002d0
034003700390034002d0039006600340062002d00370032006200340033003900610064006
5003100620038007d0000000000'
, 2))


SOFTWARE\Policies\Microsoft\Windows\IPSec\Policy\Local\i[secNFA{45dd9c22-ba82-4112-ad89-83a1a3ba4c10}

이라는 값이  표시됩니다. 하지만 이게 다일까요?

다시한번 해보죠...
이번엔 위의 바이너리 값을 두개로 나누겠습니다.
MsgBox(0, '이진값을 문자열로 변경', BinaryToString('0x'&'53004f004600540057004100520045005c0050006f006c00690063
006900650073005c004d006900630072006f0073006f00660074005c00570069006e0064006
f00770073005c00490050005300650063005c0050006f006c006900630079005c004c006f00
630061006c005c00690070007300650063004e00460041007b0034003500640064003900630
0320032002d0062006100380032002d0034003100310032002d0061006400380039002d0038
00330061003100610033006200610034006300310030007d00'
, 2) & @CRLF & @CRLF & BinaryToString('0x'&'53004f004600540057004100520045005c0050006f006c00690063
006900650073005c004d006900630072006f0073006f00660074005c00570069006e0064006
f00770073005c00490050005300650063005c0050006f006c006900630079005c004c006f00
630061006c005c00690070007300650063004e00460041007b0035003700370066006600300
0650065002d0066003900350032002d0034003700390034002d0039006600340062002d0037
00320062003400330039006100640065003100620038007d00'
, 2))


SOFTWARE\Policies\Microsoft\Windows\IPSec\Policy\Local\ipsecNFA{45dd9c22-ba82-4112-ad89-83a1a3ba4c10}

SOFTWARE\Policies\Microsoft\Windows\IPSec\Policy\Local\ipsecNFA{577ff0ee-f952-4794-9f4b-72b439ade1b8}

두줄의 값이 나타났나요?
이렇게 차이가 나타나는 이유는 중간에 @LF 즉 줄바꿈 문자가 들어가 있습니다. 이로인해 그 뒤를 읽지 못하는 것이죠..
바이너리 값을 읽어 들일 때 주의한 것은 하나의 문자가 2 바이트에 의해 움직인다는 것입니다.
바이너리 값 '5300'이 문자열값 'S'인 것이죠. 이렇게 4개씩 분리해 가다보면 바이너리값이 '0000'인 항목을 만날 수 있습니다.
'0000'을 만나면 줄이 바뀐다고 인식해 주면 됩니다.

전 다음과 같은 방식으로 데이터를 분리해 냈습니다.

#include <Array.au3>

local $binary
Local $aString[2]
$aString[0] = 1
$aString[1] = ''
Do
    $tmp = StringLeft($binary, 4)
    $binary = StringTrimLeft($binary, 4)
    if $tmp = '' then
        ExitLoop
    ElseIf $tmp = '0000' Then
        _ArrayAdd($aString, '')
        $aString[0] = $aString[0] + 1
    Else
        $aString[$aString[0]] = $aString[$aString[0]] & $tmp
    EndIf
Until 0

For $k = 1 to $aString[0]
    $aString[$k] = BinaryToString('0x'&$aString[$k], 2)
Next

_ArrayDisplay($aString)


REG_MULTI_SZ의 경우 줄바꿈 문자도 포함해 보내줘야 하는데...
@LF를 줄바꿈 문자로 사용합니다. AutoIT 도움말의 RegWrite()함수 예제를 보면 잘 나타나 있습니다 ^^:

REG_QWORD는.....AutoIt에서 아직 처리하지 못하더군요...그래서 이녀석은 패스~

흐.. 아직 모자라는 부분이 많습니다...
뭔가 궁금한게 있다면 언제든 들이대 주세요 ㅋㅋㅋ

댓글 없음:

댓글 쓰기