2012-01-12 2 views
0

IDA pro를 사용하여 실행 파일을 디스 어셈블했습니다. 내 목표는 __usercall 함수를 연결하는 것입니다. 나는 내가 typedef thefunction 수 없기 때문에 내 C++ 코드 inine asm 함께 __usercall 래핑 할 필요가 있음을 알고 있습니다. 하지만 어떻게 작동하는지 모르겠습니다.인라인 asm을 사용하여 사용자 호출 후크

나는 함수가 매개 변수로 객체를 취하고 계산 된 값이 저장 될 매개 변수로 * Vector3을 사용한다는 것을 알고있다. 어떤 param이 될지 쉽게 알 수 있습니까 ?? (긴 코드에 대한 죄송)

char __usercall sub_572EA0<al>(int a1<ecx>, int a2<edx>, int a3<eax>, int a4) 
{ 
    int v4; // [email protected]                
    int v5; // [email protected]                
    float v6; // [email protected]               
    char v7; // [email protected]                
    int v8; // [email protected]                
    char result; // [email protected]              
    int v10; // [sp+Ch] [bp-74h]@2            
    float v11; // [sp+10h] [bp-70h]@4           
    float v12; // [sp+14h] [bp-6Ch]@4           
    float v13; // [sp+18h] [bp-68h]@5           
    float v14; // [sp+1Ch] [bp-64h]@5           
    float v15; // [sp+20h] [bp-60h]@5           
    float v16; // [sp+24h] [bp-5Ch]@10           
    float v17; // [sp+28h] [bp-58h]@10           
    float v18; // [sp+2Ch] [bp-54h]@10           
    char v19; // [sp+30h] [bp-50h]@10           
    float v20; // [sp+3Ch] [bp-44h]@4           
    float v21; // [sp+40h] [bp-40h]@4           
    float v22; // [sp+44h] [bp-3Ch]@4           
    float v23; // [sp+54h] [bp-2Ch]@7           

    v4 = a3;                  
    v5 = a1;                  
    if (a3)                 
    {                   
    LODWORD(v6) = sub_55A920(*(_DWORD *)(a1 + 208));       
    if (!sub_53ADD0(              
       v5,                
       v6,                
       v4,                
       (int)&v10))              
    {                   
     v7 = sub_4EC240(v4);             
     sub_4E3ED0(               
      1,                 
      "Cannot find tag [%s]\n",   
      v7);                
    }                   
    }                   
    else                   
    {                   
    sub_572BE0();                
    *(float *)&v10 = *(float *)(v5 + 20) + v20;        
    v11 = *(float *)(v5 + 24) + v21;           
    v12 = *(float *)(v5 + 28) + v22;           
    }                   
    v8 = dword_8FF12C;               
    v13 = flt_96A218;               
    v14 = flt_96A21C;               
    v15 = flt_96A220;               
    if (dword_8FF12C == 2047)             
    v8 = dword_8FF1D0;              
    sub_462250(                 
    &v23,                  
    &v13,                  
    &v10,                  
    &unk_82D6A0,                
    v8,                  
    8400899);                 
    if (1.0 == v23                
    || (unsigned __int16)sub_492C50(&v23) == *(_DWORD *)(v5 + 208)    
    || *(_UNKNOWN **)(v5 + 364) == &unk_FFFFFF         
    && (v16 = v13                
      + (*(float *)&v10 - v13)           
      * v23,                
     v17 = (v11 - v14) * v23 + v14,           
     v18 = v23 * (v12 - v15) + v15,           
     sub_4C35B0(               
      &v16,                
      v5 + 20,               
      v5 + 32,               
      &v19),                
     sub_432850(               
      *(_DWORD *)(v5 + 348),            
      &v19)))               
    result = sub_550250(a4, &v13, &v10);          
    else                   
    result = 0;                
    return result;                
} 

ASM은입니다 probaly 잘못이 같은 가까운 것 ??

// Don't know what params goes where, ie: where the Vec3 goes and where the object goes 
int __stdcall func_hook(param1, param2, param3, param4); 

// Where to put the address? -->> 0x572EA0 

// char __usercall sub_572EA0<al>(int a1<ecx>, int a2<edx>, int a3<eax>, int a4); 
__declspec(naked) void func_hook() 
{__asm{ 
    push ebp 
    mov ebp, esp 
    mov ecx param1 
    mov edx param2 
    mov eax param3 
    push param4 
    call func_hook 
    leave 
    ret 
}} 

이 코드에서 누락 된 한 가지는 usercall (0x572EA0)의 주소입니다. 그걸 어디에 넣어야할지 모르겠다. ...

이것은 프로그램이 함수를 호출하는 방법이다. 이 호출은 맨 아래에 있습니다 : 당신이 후킹하는 기능 http://i43.tinypic.com/2mez9c8.jpg

+0

당신은 exe를 디버깅 할 수있는 방법을 타겟 프로그램이 함수를 호출 참조하십시오? '__usercall '은 종종 함수가 컴파일러에 의해 최적화된다는 것을 의미합니다. 표준 함수 호출 규칙을 따르지 않습니다. – user685684

+0

@ user685684 스크린 샷을 추가했습니다. 복사 할 부분이 확실하지 않았습니다. __userfunction에 대한 호출이 스크린 샷 하단에 나타납니다 (빨간색 테두리로 표시). – w00

+1

무슨 의미입니까? 디버거를 사용하거나 후크 기능을 사용하여 해당 레지스터의 값을보고 그 의미를 추측 할 수 있습니다. – user685684

답변

2

Borland __fastcall하지 __usercall입니다 (사실 실제로 그런 규칙, "알 수없는 대회"의 그것의 단지 IDA의 버전이 없음).

인라인 어셈블리, ECX, EDXEAX 스크래치 레지스터, 그래서 우리가 그들을 보존 할 필요가 없습니다, 그리고 통화가 잘 그래서 우리는 스택에 대해 걱정할 필요가 없습니다 foermed되어 함께이 후킹의 관점에서

:

static DWORD the_hook_address = 0x572EA0; 
//init this somewhere with the correct (Base + RVA) address in case of module relocation (from ASLR etc.) 
__declspec(naked) bool __stdcall the_hook(int a1, int a2, int a3, int a3) 
{ 
    __asm 
    { 
     MOV ECX,[ESP + 4]//a1 
     MOV EDX,[ESP + 8]//a2 
     MOV EAX,[ESP + 12]//a3 
     PUSH [ESP + 16]//a4 
     CALL the_hook_address 
     RETN 16 //4 * 4 args 
    } 
} 

I는 함수 파라미터 및 상기 계산 된 값이 저장 될 것이다 파라미터로서 * Vector3 같은 오브젝트를 안다. 거기에 쉬운 방법은 어떤 param 될 것이라고 말할 수 있습니까 ??

'easyness'는 그 다음 사용하여 액세스되는 임시로 이동 볼 수 있기 때문에이 경우에는 내가 그 a1을 말하고 싶지만, 리버스 엔지니어링에서 당신이 REing중인 프로그램에 대한 사용자의 경험에 따라 달라집니다 일반적으로 대부분의 응용 프로그램이 벡터 구성 요소에 사용하는 대부분의 벡터 (또한 대부분의 벡터에는 3 개의 구성 요소가 있음)는 3 float을 추출하기위한 포인터 표기법 (IDA의 알 수없는 구조체 표현 방법)입니다. 또한 실제로 작동중인 호출을 디버그하고 포인터가 무엇인지 알아보고 함수 호출 사이트 등을 살펴 보시면 큰 도움이됩니다. 이런 이유로 나는 REly에 ollydbg를 사용하여 IDA 실행 흐름 그래프를 보완하여 까다로운 점프 시퀀스 (함수에서 20 + goto s 생각 : <)

+0

설명 주셔서 감사합니다. 정말 도움이되었습니다. – w00

관련 문제