Здравствуйте, дорогие форумчане!
Затупаю на одном моменте и не могу обойти проверку ключа в одной функции. Есть установщик программы (ссылка на файлообменик). Сама программа написана на Delphi, IDR отлично отрабатывает, показывает всё, что мне нужно.
В программе реализована проверка на USB HASP ключ и проверка на лицензию. Везде на клики кнопок навешана функция проверки ключа, для примера:
Как видно уже из декомпилированного кода, если пропустить проверку, то дальше по условию код выполняется и всем хорошо.
Но при вызове двух кликов - на открытие файла и создание нового файла, вызов метода идёт с параметрами. Если его просто пропустить по JNE из-за этого приложение будет обращаться к региону памяти, к которому нет доступа и приложение падает.
Подскажите, в какой регистр что нужно записать и как правильно обойти, чтобы это не ломалось.
Дополнительно добавлю, что та же Ghidra почему-то показывает, что идет именно вызов procedure TMainForm.SettingsLicensesClick, который уже затрагивает sub_00792AD4, при этом на форме в меню вызова такой функции нет, но метод остался.
Ещё про считывание файла лицензии спросил бы, но пока вопрос в этом методе. Во вложении патч для x32dbg с обходом функций.
Затупаю на одном моменте и не могу обойти проверку ключа в одной функции. Есть установщик программы (ссылка на файлообменик). Сама программа написана на Delphi, IDR отлично отрабатывает, показывает всё, что мне нужно.
В программе реализована проверка на USB HASP ключ и проверка на лицензию. Везде на клики кнопок навешана функция проверки ключа, для примера:
C:
//----- (007904D8) --------------------------------------------------------
int __fastcall TMainForm_FileSaveClick(_BYTE *a1)
{
if ( !(unsigned __int8)((int (*)(void))loc_792AD4)() )
TCustomForm_Close(a1);
TMainForm_TrySaveFile((int)a1);
TMainForm_UpdateTreeView((int)a1);
return TMainForm_UpdateStatusbar((int)a1);
}
//----- (00790504) --------------------------------------------------------
int __fastcall TMainForm_FileSaveAsClick(_BYTE *a1)
{
if ( !(unsigned __int8)((int (*)(void))loc_792AD4)() )
TCustomForm_Close(a1);
if ( (unsigned __int8)TMainForm_GetNewFileName((int)a1, (int *)off_7C4C8C) )
TMainForm_TrySaveFile((int)a1);
TMainForm_UpdateTreeView((int)a1);
return TMainForm_UpdateStatusbar((int)a1);
}
Как видно уже из декомпилированного кода, если пропустить проверку, то дальше по условию код выполняется и всем хорошо.
Но при вызове двух кликов - на открытие файла и создание нового файла, вызов метода идёт с параметрами. Если его просто пропустить по JNE из-за этого приложение будет обращаться к региону памяти, к которому нет доступа и приложение падает.
C:
//----- (0078FEA4) --------------------------------------------------------
_DWORD *__fastcall TMainForm_FileNewClick(int a1)
{ if ( !(unsigned __int8)((int (__cdecl *)(struct _EXCEPTION_REGISTRATION_RECORD *, void *, int *))loc_792AD4)( v8, &unk_79007D, &savedregs) )
TCustomForm_Close((_BYTE *)a1);
}
//----- (007900C4) --------------------------------------------------------
int __fastcall TMainForm_FileOpenClick(int a1)
{
if ( !(unsigned __int8)((int (__cdecl *)(struct _EXCEPTION_REGISTRATION_RECORD *, void *))loc_792AD4)(v7, &unk_790358) )
TCustomForm_Close((_BYTE *)a1);
}
//----- (00790A44) --------------------------------------------------------
void __fastcall TMainForm_ToolsSendClick(_BYTE *a1)
{
_DWORD *v1; // esi
__writefsdword(0, (unsigned int)&v6);
if ( !(unsigned __int8)((int (__stdcall *)(struct _EXCEPTION_REGISTRATION_RECORD *, void *, int *))loc_792AD4)( v6,&unk_790B93, &savedregs) )
TCustomForm_Close(v11);
}
Подскажите, в какой регистр что нужно записать и как правильно обойти, чтобы это не ломалось.
C:
void FUN_00792ad4(void)
{
undefined *puVar1;
int iVar2;
int iVar3;
undefined4 *in_FS_OFFSET;
undefined4 uVar4;
undefined4 uStack_2c;
undefined *puStack_28;
undefined *puStack_24;
int local_14;
undefined local_10;
undefined4 local_c [2];
puStack_24 = &stack0xfffffffc;
local_c[0] = 0;
puStack_28 = &DAT_00792beb;
uStack_2c = *in_FS_OFFSET;
*in_FS_OFFSET = &uStack_2c;
if (*gvar_007C4420 == '\0')
{
iVar3 = 0;
puStack_24 = &stack0xfffffffc;
do {
iVar2 = FUN_005de4ab();
if (iVar2 != 0)
{
iVar2 = FUN_005de4ab();
}
if (iVar2 != 0)
{
if (iVar2 == 7) {
iVar3 = MessageDlg(*(undefined4 *)
(PTR_gvar_007C10AC_007c43e8 + (uint)(byte)*gvar_007C42C4 * 0x38 + 0x18
),1,0x28,0);
}
else {
uVar4 = 0;
local_10 = 0;
local_14 = iVar2;
Format(*(undefined4 *)
(PTR_gvar_007C10AC_007c43e8 + (uint)(byte)*gvar_007C42C4 * 0x38 + 0x20),&local_14,
0,local_c);
iVar3 = MessageDlg(local_c[0],1,4,uVar4);
}
}
}
while (((iVar2 != 0) && (iVar3 != 2)) && (iVar3 != 1));
FUN_005de5bb();
}
puVar1 = puStack_24;
*in_FS_OFFSET = uStack_2c;
puStack_24 = &LAB_00792bf2;
puStack_28 = (undefined *)0x792bea;
_UStrClr(local_c,uStack_2c,puVar1);
return;
}
Код:
//00792AC4
procedure TMainForm.SettingsLicensesClick(Sender:TObject);
begin
{*
00792AC4 mov eax,[007C4A04];^gvar_009037C8:TLicenseManagerForm
00792AC9 mov eax,dword ptr [eax]
00792ACB mov edx,dword ptr [eax]
00792ACD call dword ptr [edx+13C]
00792AD3 ret
*}
end;
//00792AD4
{*function sub_00792AD4:?;
begin
00792AD4 push ebp
00792AD5 mov ebp,esp
00792AD7 add esp,0FFFFFFF0
00792ADA push ebx
00792ADB push esi
00792ADC push edi
00792ADD xor eax,eax
00792ADF mov dword ptr [ebp-8],eax
00792AE2 xor eax,eax
00792AE4 push ebp
00792AE5 push 792BEB
00792AEA push dword ptr fs:[eax]
00792AED mov dword ptr fs:[eax],esp
00792AF0 mov eax,[007C4420];^gvar_007CA838
00792AF5 cmp byte ptr [eax],0
>00792AF8 je 00792B01
00792AFA mov bl,1
>00792AFC jmp 00792BD5
00792B01 xor ebx,ebx
00792B03 xor esi,esi
00792B05 lea eax,[ebp-4]
00792B08 push eax
00792B09 mov eax,[007C4158];^gvar_0078AB68
00792B0E push eax
00792B0F push 1
00792B11 call 005DE4AB
00792B16 mov edi,eax
00792B18 test edi,edi
>00792B1A je 00792B32
00792B1C lea eax,[ebp-4]
00792B1F push eax
00792B20 mov eax,[007C4158];^gvar_0078AB68
00792B25 push eax
00792B26 push 0FFFF4800
00792B2B call 005DE4AB
00792B30 mov edi,eax
00792B32 mov eax,edi
00792B34 sub eax,1
>00792B37 jb 00792B40
00792B39 sub eax,6
>00792B3C je 00792B44
>00792B3E jmp 00792B74
00792B40 mov bl,1
>00792B42 jmp 00792BBA
00792B44 push 0
00792B46 mov eax,[007C42C4];^gvar_007CA830
00792B4B movzx eax,byte ptr [eax]
00792B4E imul eax,eax,7
>00792B51 jno 00792B58
00792B53 call @IntOver
00792B58 mov edx,dword ptr ds:[7C43E8];^gvar_007C10AC
00792B5E mov eax,dword ptr [edx+eax*8+18]
00792B62 movzx ecx,word ptr ds:[792BFC];0x28 gvar_00792BFC
00792B69 mov dl,1
00792B6B call MessageDlg
00792B70 mov esi,eax
>00792B72 jmp 00792BBA
00792B74 push 0
00792B76 lea eax,[ebp-8]
00792B79 push eax
00792B7A mov eax,[007C42C4];^gvar_007CA830
00792B7F movzx eax,byte ptr [eax]
00792B82 imul eax,eax,7
>00792B85 jno 00792B8C
00792B87 call @IntOver
00792B8C mov edx,dword ptr ds:[7C43E8];^gvar_007C10AC
00792B92 mov eax,dword ptr [edx+eax*8+20]
00792B96 mov dword ptr [ebp-10],edi
00792B99 mov byte ptr [ebp-0C],0
00792B9D lea edx,[ebp-10]
00792BA0 xor ecx,ecx
00792BA2 call Format
00792BA7 mov eax,dword ptr [ebp-8]
00792BAA movzx ecx,word ptr ds:[792C00];0x4 gvar_00792C00
00792BB1 mov dl,1
00792BB3 call MessageDlg
00792BB8 mov esi,eax
00792BBA test edi,edi
>00792BBC je 00792BCC
00792BBE cmp esi,2
>00792BC1 je 00792BCC
00792BC3 cmp esi,1
>00792BC6 jne 00792B05
00792BCC mov eax,dword ptr [ebp-4]
00792BCF push eax
00792BD0 call 005DE5BB
00792BD5 xor eax,eax
00792BD7 pop edx
00792BD8 pop ecx
00792BD9 pop ecx
00792BDA mov dword ptr fs:[eax],edx
00792BDD push 792BF2
00792BE2 lea eax,[ebp-8]
00792BE5 call @UStrClr
00792BEA ret
>00792BEB jmp @HandleFinally
>00792BF0 jmp 00792BE2
00792BF2 mov eax,ebx
00792BF4 pop edi
00792BF5 pop esi
00792BF6 pop ebx
00792BF7 mov esp,ebp
00792BF9 pop ebp
00792BFA ret
end;*}
Ещё про считывание файла лицензии спросил бы, но пока вопрос в этом методе. Во вложении патч для x32dbg с обходом функций.
Вложения
Последнее редактирование: