Исследование XChat 2.6.7
Программа имеет ограни4ение на использование 30 дней, о 4ем после их окон4ания нагло пишет в НАГе. Грузим ЕХЕ в ольку. Первой мыслью было банально поставить брякки на все команды вида CMP reg, 1Eh, CMP reg, 1Dh, CMP reg, 1Fh, которые предположительно будут проверять коли4ество дней прошедших и константно вшитых в код тридцати. Программа оказалась немного сложнее и следующим ходом было решено проверять обращения к файлом и реестру за датами. На этот раз сработало, программа с4итывает с реестра время установки и сравнивает ее с теперешней датой.
стек на момент вызова с4итывание параметра клю4а:
не желая замора4иваться с тонкостях алгоритма проверки даты, дотрейсим до этого места
если "идти" обы4ном ходом алгоритма, то увидим наг, говорящий 4то у нас закон4илось время триала. Если модифицируем флаг и пойдем на 00435736, то
увидим и наг, и главное окно программы. Стало быть в обоих слу4аях вызывается одна и та же функция. Найти ее можно поставив бряк на вызов апи полу4ения времени (в нашем слу4ае JMP.&msvcrt.time), либо просто протрейсив всю функцию пошагово до выявления подфункции, вызывающей
непосредственно НАГ(который, кстате, можно обнаружить по перекрестным
ссылкам на строки "register" и т.д.).
Вот ее вызов:
0041E368 E8 AB84FEFF CALL unpacked.00406818
и ее листинг:
Нас заинтересует вот эта 4асть:
0040681D 833D D0DD4500 00 CMP DWORD PTR DS:[45DDD0],0
00406824 75 5F JNZ SHORT unpacked.00406885
В слу4ае нулевого зна4ения [45DDD0] будет вызываться НАГ, ина4е мы прыгаем
на
00406885 E8 26F30200 CALL <JMP.&minigtk.#250>,
4то есть ни4ем иным как функция вызова главного диалога программы. Для
пат4а ограни4имся изменением условного перехода (.00406824) безусловным.
Для завершения взлома, нам нужно подменить надпись "Evaluation version" в
окне "О программе" на свой ник
Поскольку в ресурсах и перекрестных
ссылках исполняемого ЕХЕ этой строки нет, то можно либо поискать ссылки на
строки "registered" и т.д. (в надежде, 4то выводящий их код будет рядом),
либо (4то надежнее) поставить апаратный!!! бряк на доступ к байтам
(поскольку они гарантирована будут с4итываться программой для вывода в
окно перед выводом строки о триальности) и протрейсив немного кода в
дополнительных либах после срабатывания то4ки останова попасть сюда:
После проверки можно с уверенностю сказать, 4то в EAX загрузится
указатель(ведь до проверки он имел нулевое зна4ени) на строку "Evaluation
version". 4тобы избавиться от этой назойливой строки, нужно до проверки в
EAX забить указатель на строку, содержащую наш ник. 4тобы лишний раз не
пат4ить бинарник и не добавлять по какому-то адресу в него ник, можно
упростить себе задание. Посмотрим в окне дампа (ECX -> Follow in dump)
содержание буфера, указатель на который находится в ECX. Тут сохранена
какая-то константа "00A42C18 43 50 31 32 35 31 utf8". Но интересней
другое, а именно то, 4то выше (ниже по зна4ению) на 78h находится
прос4итанный программой ник(предположительно UserName на канале).
Попытаемся его заюзать. Для этого вместо операции проверки внедрим функцию загрузки ECX(указателя на буфер) в EAX и отнимем от него 78h (сомнительно, 4то даный финт будет работать вне пределах одной машини, так 4то советую либо повозиться с поиском "своего" смещения в буфере, либо всетаки дописать свой ник в бинарник и при вызове вывода зарегистрированного имени указывать его адрес
пат4и:
00435734 7E 11 JLE SHORT unpacked.00435747
на
00435734 90 90 nop nop
00406824 75 5F JNZ SHORT unpacked.00406885
на
00406824 EB 5F JMP SHORT unpacked.00406885
004010FD A1 D0DD4500 MOV EAX,DWORD PTR DS:[45DDD0]
00401102 3BC7 CMP EAX,EDI
00401104 75 03 JNZ SHORT unpacked.00401109
на
004010FD 8BC1 MOV EAX,ECX
004010FF 2D C8000000 SUB EAX,078
00401104 EB 03 JMP SHORT unpacked.00401109
gl hf!
Программа имеет ограни4ение на использование 30 дней, о 4ем после их окон4ания нагло пишет в НАГе. Грузим ЕХЕ в ольку. Первой мыслью было банально поставить брякки на все команды вида CMP reg, 1Eh, CMP reg, 1Dh, CMP reg, 1Fh, которые предположительно будут проверять коли4ество дней прошедших и константно вшитых в код тридцати. Программа оказалась немного сложнее и следующим ходом было решено проверять обращения к файлом и реестру за датами. На этот раз сработало, программа с4итывает с реестра время установки и сравнивает ее с теперешней датой.
Код:
004353F3 55 PUSH EBP
004353F4 89E5 MOV EBP,ESP
004353F6 57 PUSH EDI
004353F7 56 PUSH ESI
004353F8 53 PUSH EBX
004353F9 81EC 6C020000 SUB ESP,26C
004353FF 6A 00 PUSH 0
00435401 C785 90FDFFFF 00>MOV DWORD PTR SS:[EBP-270],0
0043540B E8 D27F0000 CALL <JMP.&msvcrt.time>
00435410 5B POP EBX
00435411 8985 8CFDFFFF MOV DWORD PTR SS:[EBP-274],EAX
00435417 31D2 XOR EDX,EDX
00435419 31FF XOR EDI,EDI
0043541B 0FB687 9C2D4400 MOVZX EAX,BYTE PTR DS:[EDI+442D9C]
00435422 47 INC EDI
00435423 C0E0 04 SHL AL,4
00435426 0A87 9C2D4400 OR AL,BYTE PTR DS:[EDI+442D9C]
0043542C 47 INC EDI
0043542D 88842A B4FDFFFF MOV BYTE PTR DS:[EDX+EBP-24C],AL
00435434 42 INC EDX
00435435 83FF 1D CMP EDI,1D
00435438 ^76 E1 JBE SHORT unpacked.0043541B
0043543A 8D95 B0FDFFFF LEA EDX,DWORD PTR SS:[EBP-250]
00435440 8D85 B4FDFFFF LEA EAX,DWORD PTR SS:[EBP-24C]
00435446 52 PUSH EDX
00435447 68 3F000F00 PUSH 0F003F
0043544C 6A 00 PUSH 0
0043544E 50 PUSH EAX
0043544F 68 01000080 PUSH 80000001
00435454 E8 6F0D0000 CALL <JMP.&ADVAPI32.RegOpenKeyExA> !!
00435459 31D2 XOR EDX,EDX
0043545B 85C0 TEST EAX,EAX
0043545D 75 10 JNZ SHORT unpacked.0043546F
0043545F FFB5 B0FDFFFF PUSH DWORD PTR SS:[EBP-250]
00435465 E8 640D0000 CALL <JMP.&ADVAPI32.RegCloseKey>
0043546A BA 01000000 MOV EDX,1
0043546F 85D2 TEST EDX,EDX
00435471 8DB5 F4FEFFFF LEA ESI,DWORD PTR SS:[EBP-10C]
00435477 8D95 B4FDFFFF LEA EDX,DWORD PTR SS:[EBP-24C]
0043547D 0F85 0E010000 JNZ unpacked.00435591
00435483 8D85 ACFDFFFF LEA EAX,DWORD PTR SS:[EBP-254]
00435489 50 PUSH EAX
0043548A 52 PUSH EDX
0043548B 68 01000080 PUSH 80000001
00435490 E8 3F0D0000 CALL <JMP.&ADVAPI32.RegCreateKeyA> !!
00435495 85C0 TEST EAX,EAX
00435497 0F85 D7000000 JNZ unpacked.00435574
0043549D FFB5 ACFDFFFF PUSH DWORD PTR SS:[EBP-254]
004354A3 E8 260D0000 CALL <JMP.&ADVAPI32.RegCloseKey>
004354A8 FFB5 8CFDFFFF PUSH DWORD PTR SS:[EBP-274]
004354AE 8DBD F4FEFFFF LEA EDI,DWORD PTR SS:[EBP-10C]
004354B4 31DB XOR EBX,EBX
004354B6 68 BA2D4400 PUSH unpacked.00442DBA ;
ASCII "%x"
004354BB 68 00010000 PUSH 100
004354C0 57 PUSH EDI
004354C1 E8 167F0000 CALL <JMP.&msvcrt._snprintf>
004354C6 FC CLD
004354C7 83C9 FF OR ECX,FFFFFFFF
004354CA 31C0 XOR EAX,EAX
004354CC F2:AE REPNE SCAS BYTE PTR ES:[EDI]
004354CE F7D1 NOT ECX
004354D0 31FF XOR EDI,EDI
004354D2 49 DEC ECX
004354D3 83C4 10 ADD ESP,10
004354D6 39CB CMP EBX,ECX
004354D8 7D 15 JGE SHORT unpacked.004354EF
004354DA 0FBE842F F4FEFFF>MOVSX EAX,BYTE PTR DS:[EDI+EBP-10C]
004354E2 83E8 30 SUB EAX,30
004354E5 0FAFC7 IMUL EAX,EDI
004354E8 47 INC EDI
004354E9 01C3 ADD EBX,EAX
004354EB 39CF CMP EDI,ECX
004354ED ^EB E9 JMP SHORT unpacked.004354D8
004354EF FFB5 8CFDFFFF PUSH DWORD PTR SS:[EBP-274]
004354F5 53 PUSH EBX
004354F6 8D9D F4FDFFFF LEA EBX,DWORD PTR SS:[EBP-20C]
004354FC 68 BD2D4400 PUSH unpacked.00442DBD ;
ASCII "%06d%x"
00435501 68 00010000 PUSH 100
00435506 53 PUSH EBX
00435507 E8 D07E0000 CALL <JMP.&msvcrt._snprintf>
0043550C 83C4 14 ADD ESP,14
0043550F 8D95 A8FDFFFF LEA EDX,DWORD PTR SS:[EBP-258]
00435515 8D85 B4FDFFFF LEA EAX,DWORD PTR SS:[EBP-24C]
0043551B 52 PUSH EDX
0043551C 68 3F000F00 PUSH 0F003F
00435521 6A 00 PUSH 0
00435523 50 PUSH EAX
00435524 68 01000080 PUSH 80000001
00435529 E8 9A0C0000 CALL <JMP.&ADVAPI32.RegOpenKeyExA> !!
0043552E 85C0 TEST EAX,EAX
00435530 75 42 JNZ SHORT unpacked.00435574
00435532 FC CLD
00435533 83C9 FF OR ECX,FFFFFFFF
00435536 89DF MOV EDI,EBX
00435538 F2:AE REPNE SCAS BYTE PTR ES:[EDI]
0043553A F7D1 NOT ECX
0043553C 49 DEC ECX
0043553D 51 PUSH ECX
0043553E 53 PUSH EBX
0043553F 6A 01 PUSH 1
00435541 6A 00 PUSH 0
00435543 68 C42D4400 PUSH unpacked.00442DC4 ;
ASCII "installed"
00435548 FFB5 A8FDFFFF PUSH DWORD PTR SS:[EBP-258]
0043554E E8 870C0000 CALL <JMP.&ADVAPI32.RegSetValueExA> !!
00435553 85C0 TEST EAX,EAX
00435555 74 0D JE SHORT unpacked.00435564
00435557 FFB5 A8FDFFFF PUSH DWORD PTR SS:[EBP-258]
0043555D E8 6C0C0000 CALL <JMP.&ADVAPI32.RegCloseKey>
00435562 EB 10 JMP SHORT unpacked.00435574
00435564 FFB5 A8FDFFFF PUSH DWORD PTR SS:[EBP-258]
0043556A E8 5F0C0000 CALL <JMP.&ADVAPI32.RegCloseKey>
0043556F ^E9 A3FEFFFF JMP unpacked.00435417
00435574 68 10000100 PUSH 10010 ;
UNICODE "=C:=C:\Program Files\xchat"
00435579 68 CE2D4400 PUSH unpacked.00442DCE ;
ASCII "Error"
0043557E 68 D42D4400 PUSH unpacked.00442DD4 ;
ASCII "Cannot access the registry."
00435583 6A 00 PUSH 0
00435585 E8 380C0000 CALL <JMP.&USER32.MessageBoxA>
0043558A 6A 01 PUSH 1
0043558C E8 697E0000 CALL <JMP.&msvcrt.exit>
00435591 FF05 C8DD4500 INC DWORD PTR DS:[45DDC8]
00435597 8D85 A4FDFFFF LEA EAX,DWORD PTR SS:[EBP-25C]
0043559D 50 PUSH EAX
0043559E 68 19000200 PUSH 20019
004355A3 6A 00 PUSH 0
004355A5 52 PUSH EDX
004355A6 68 01000080 PUSH 80000001
004355AB FF0D 20D04500 DEC DWORD PTR DS:[45D020]
004355B1 C785 A0FDFFFF 00>MOV DWORD PTR SS:[EBP-260],100
004355BB E8 080C0000 CALL <JMP.&ADVAPI32.RegOpenKeyExA>!!!
004355C0 85C0 TEST EAX,EAX
004355C2 ^0F85 E0FEFFFF JNZ unpacked.004354A8
004355C8 8D85 A0FDFFFF LEA EAX,DWORD PTR SS:[EBP-260]
004355CE 50 PUSH EAX
004355CF 8D85 9CFDFFFF LEA EAX,DWORD PTR SS:[EBP-264]
004355D5 56 PUSH ESI
004355D6 50 PUSH EAX
004355D7 6A 00 PUSH 0
004355D9 68 C42D4400 PUSH unpacked.00442DC4 ;
ASCII "installed"
004355DE FFB5 A4FDFFFF PUSH DWORD PTR SS:[EBP-25C]
004355E4 E8 F70B0000 CALL <JMP.&ADVAPI32.RegQueryValueExA>
стек на момент вызова с4итывание параметра клю4а:
Код:
0012FCAC 00000078 |hKey = 78
0012FCB0 00442DC4 |ValueName = "installed"
0012FCB4 00000000 |Reserved = NULL
0012FCB8 0012FCD8 |pValueType = 0012FCD8
0012FCBC 0012FE30 |Buffer = 0012FE30
0012FCC0 0012FCDC \pBufSize = 0012FCDC
не желая замора4иваться с тонкостях алгоритма проверки даты, дотрейсим до этого места
Код:
00435734 7E 11 JLE SHORT unpacked.00435747
00435736 B8 01000000 MOV EAX,1
0043573B E8 5EF8FFFF CALL unpacked.00434F9E
00435740 E8 8A86FEFF CALL unpacked.0041DDCF
00435745 EB 07 JMP SHORT unpacked.0043574E
00435747 31C0 XOR EAX,EAX
00435749 E8 50F8FFFF CALL unpacked.00434F9E
0043574E 8D65 F4 LEA ESP,DWORD PTR SS:[EBP-C]
00435751 5B POP EBX
00435752 5E POP ESI
00435753 5F POP EDI
00435754 5D POP EBP
00435755 C3 RETN
если "идти" обы4ном ходом алгоритма, то увидим наг, говорящий 4то у нас закон4илось время триала. Если модифицируем флаг и пойдем на 00435736, то
увидим и наг, и главное окно программы. Стало быть в обоих слу4аях вызывается одна и та же функция. Найти ее можно поставив бряк на вызов апи полу4ения времени (в нашем слу4ае JMP.&msvcrt.time), либо просто протрейсив всю функцию пошагово до выявления подфункции, вызывающей
непосредственно НАГ(который, кстате, можно обнаружить по перекрестным
ссылкам на строки "register" и т.д.).
Вот ее вызов:
0041E368 E8 AB84FEFF CALL unpacked.00406818
и ее листинг:
Код:
00406818 55 PUSH EBP
00406819 8BEC MOV EBP,ESP
0040681B 51 PUSH ECX
0040681C 51 PUSH ECX
0040681D 833D D0DD4500 00 CMP DWORD PTR DS:[45DDD0],0 !!!
00406824 75 5F JNZ SHORT unpacked.00406885
00406826 53 PUSH EBX
00406827 56 PUSH ESI
00406828 57 PUSH EDI
00406829 8B3D C0204400 MOV EDI,DWORD PTR DS:[<&msvcrt._open>] ;
msvcrt._open
0040682F 68 00800000 PUSH 8000
00406834 BE 9CD24400 MOV ESI,unpacked.0044D29C ;
ASCII "./inst.conf"
00406839 56 PUSH ESI
0040683A FFD7 CALL EDI
0040683C 8BD8 MOV EBX,EAX
0040683E 83FB FF CMP EBX,-1
00406841 59 POP ECX
00406842 59 POP ECX
00406843 75 5C JNZ SHORT unpacked.004068A1
00406845 6A 00 PUSH 0
00406847 FF15 D0214400 CALL DWORD PTR DS:[<&msvcrt.time>] ;
msvcrt.time
0040684D C70424 01830000 MOV DWORD PTR SS:[ESP],8301
00406854 56 PUSH ESI
00406855 8945 FC MOV DWORD PTR SS:[EBP-4],EAX
00406858 FFD7 CALL EDI
0040685A 8BF8 MOV EDI,EAX
0040685C 3BFB CMP EDI,EBX
0040685E 59 POP ECX
0040685F 59 POP ECX
00406860 74 20 JE SHORT unpacked.00406882
00406862 6A 04 PUSH 4
00406864 8D45 FC LEA EAX,DWORD PTR SS:[EBP-4]
00406867 50 PUSH EAX
00406868 57 PUSH EDI
00406869 FF15 B8204400 CALL DWORD PTR DS:[<&msvcrt._write>] ;
msvcrt._write
0040686F 57 PUSH EDI
00406870 FF15 C4204400 CALL DWORD PTR DS:[<&msvcrt._close>] ;
msvcrt._close
00406876 83C4 10 ADD ESP,10
00406879 6A 07 PUSH 7
0040687B 56 PUSH ESI
0040687C FF15 6C204400 CALL DWORD PTR DS:[<&KERNEL32.SetFileAtt>;
kernel32.SetFileAttributesA
00406882 5F POP EDI
00406883 5E POP ESI
00406884 5B POP EBX
00406885 E8 26F30200 CALL <JMP.&minigtk.#250>
0040688A 833D D4204600 00 CMP DWORD PTR DS:[4620D4],0
00406891 74 0C JE SHORT unpacked.0040689F
00406893 68 B80B0000 PUSH 0BB8
00406898 FF15 A4214400 CALL DWORD PTR DS:[<&msvcrt._sleep>] ;
msvcrt._sleep
0040689E 59 POP ECX
0040689F C9 LEAVE
004068A0 C3 RETN
Нас заинтересует вот эта 4асть:
0040681D 833D D0DD4500 00 CMP DWORD PTR DS:[45DDD0],0
00406824 75 5F JNZ SHORT unpacked.00406885
В слу4ае нулевого зна4ения [45DDD0] будет вызываться НАГ, ина4е мы прыгаем
на
00406885 E8 26F30200 CALL <JMP.&minigtk.#250>,
4то есть ни4ем иным как функция вызова главного диалога программы. Для
пат4а ограни4имся изменением условного перехода (.00406824) безусловным.
Для завершения взлома, нам нужно подменить надпись "Evaluation version" в
окне "О программе" на свой ник
ссылках исполняемого ЕХЕ этой строки нет, то можно либо поискать ссылки на
строки "registered" и т.д. (в надежде, 4то выводящий их код будет рядом),
либо (4то надежнее) поставить апаратный!!! бряк на доступ к байтам
Код:
00444856 . 32 30 30 36 0A>ASCII "2006
<b>Registe"
00444866 . 72 65 64 20 74>ASCII "red to</b>:
%s
"
(поскольку они гарантирована будут с4итываться программой для вывода в
окно перед выводом строки о триальности) и протрейсив немного кода в
дополнительных либах после срабатывания то4ки останова попасть сюда:
Код:
00401102 3BC7 CMP EAX,EDI
00401104 75 03 JNZ SHORT unpacked.00401109
00401106 8D45 E8 LEA EAX,DWORD PTR SS:[EBP-18]
00401109 8945 F8 MOV DWORD PTR SS:[EBP-8],EAX
0040110C FF15 70204400 CALL DWORD PTR DS:[<&KERNEL32.GetVersion>;
kernel32.GetVersion
00401112 3D 00000080 CMP EAX,80000000
00401117 B8 D8484400 MOV EAX,unpacked.004448D8 ;
ASCII "Yes"
0040111C 72 05 JB SHORT unpacked.00401123
0040111E B8 D4484400 MOV EAX,unpacked.004448D4 ;
ASCII "No"
00401123 FF75 F8 PUSH DWORD PTR SS:[EBP-8]
00401126 50 PUSH EAX
00401127 FF75 FC PUSH DWORD PTR SS:[EBP-4]
0040112A E8 B7D50100 CALL unpacked.0041E6E6
0040112F 50 PUSH EAX
00401130 68 B8484400 PUSH unpacked.004448B8 ;
ASCII "A multiplatform IRC Client"
00401135 E8 A4460300 CALL <JMP.&minigtk.#156>
0040113A 59 POP ECX
0040113B 50 PUSH EAX
0040113C 68 E0474400 PUSH unpacked.004447E0 ;
ASCII 3C,"span size="x-large"><b>XChat 2.6.7</b></span>
%s
%s
<b>Cod"
00401141 8D85 E8FDFFFF LEA EAX,DWORD PTR SS:[EBP-218]
00401147 68 00020000 PUSH 200
0040114C 50 PUSH EAX
После проверки можно с уверенностю сказать, 4то в EAX загрузится
указатель(ведь до проверки он имел нулевое зна4ени) на строку "Evaluation
version". 4тобы избавиться от этой назойливой строки, нужно до проверки в
EAX забить указатель на строку, содержащую наш ник. 4тобы лишний раз не
пат4ить бинарник и не добавлять по какому-то адресу в него ник, можно
упростить себе задание. Посмотрим в окне дампа (ECX -> Follow in dump)
содержание буфера, указатель на который находится в ECX. Тут сохранена
какая-то константа "00A42C18 43 50 31 32 35 31 utf8". Но интересней
другое, а именно то, 4то выше (ниже по зна4ению) на 78h находится
прос4итанный программой ник(предположительно UserName на канале).
Попытаемся его заюзать. Для этого вместо операции проверки внедрим функцию загрузки ECX(указателя на буфер) в EAX и отнимем от него 78h (сомнительно, 4то даный финт будет работать вне пределах одной машини, так 4то советую либо повозиться с поиском "своего" смещения в буфере, либо всетаки дописать свой ник в бинарник и при вызове вывода зарегистрированного имени указывать его адрес
пат4и:
00435734 7E 11 JLE SHORT unpacked.00435747
на
00435734 90 90 nop nop
00406824 75 5F JNZ SHORT unpacked.00406885
на
00406824 EB 5F JMP SHORT unpacked.00406885
004010FD A1 D0DD4500 MOV EAX,DWORD PTR DS:[45DDD0]
00401102 3BC7 CMP EAX,EDI
00401104 75 03 JNZ SHORT unpacked.00401109
на
004010FD 8BC1 MOV EAX,ECX
004010FF 2D C8000000 SUB EAX,078
00401104 EB 03 JMP SHORT unpacked.00401109
gl hf!