2015-04-24 14 views
6

Tôi có một chức năng windows 7 callgate mà tôi sử dụng để gọi chức năng NT trực tiếp:Đang cố gắng để tạo ra một cửa sổ 8 syscall chức năng callgate

//Windows 7 syscall 

__declspec(naked) 
NTSTATUS __fastcall wow64 (DWORD ecxId, char *edxArgs) 
{ 
    __asm 
    { 
     mov eax, ecx; 
     mov ecx, m_param; 
     call DWORD ptr fs:[0xc0]; 
     add esp, 0x4; 
     retn; 
    }; 
} 

NTSTATUS callGate (DWORD id, ...) 
{ 
    va_list valist; 
    va_start(valist,id); 
    return wow64(id,valist); 
} 

//Example NTClose function 
NTSTATUS closeHandle (void *object) 
{ 
    m_param = 0; 
    return callGate (0xc, object); 
} 

Tôi cố gắng để làm điều tương tự cho các cửa sổ 8.1. Tôi đã cập nhật tất cả các chỉ mục cuộc gọi chức năng; Tuy nhiên tôi nhận thấy chức năng callgate thực tế là khá khác nhau trên cửa sổ 8.1:

Dưới đây là những gì các cổng gọi thực tế trông như thế (nằm trong ntdll.dll) cho hàm ZwCreateThreadEx

mov eax, 0xA5 //the call index 
xor ecx, ecx //(m_param) 
lea edx, dword ptr ss:[esp + 0x4] //this causes an sp-analysis failure in IDA 
call dword ptr fs:[0xC0] 
add esp, 0x4 
retn 0x2C 

Bây giờ đây là CHÍNH XÁC cùng chức năng NT (ZwCreateThreadEx) trên windows 8.1

mov eax, 0xB0 //the call index 
call dword ptr fs:[0xC0] 
retn 0x2C //2c/4 = 11 parameters 

Tôi đã thử mọi thứ để làm việc này trên windows 8.1 nhưng không có kết quả. Tôi không thể giải thích vấn đề là gì hoặc điều gì đang xảy ra, tất cả những gì tôi biết là tôi đang thực hiện chính xác trên các cửa sổ 7.

Từ giao diện của hàm W8.1, tôi đã cố gắng tìm ra chức năng này (Không hoạt động):

DWORD dwebp,dwret,dwparams; //for saving stuff 

NTSTATUS __cdecl callGate (DWORD id, DWORD numparams, ...) 
{ 
    _asm 
    { 
     pop dwebp; //save ebp off stack 
     pop dwret; //save return address 
     pop eax; //save id 
     pop dwparams; //save param count 
     push dwret; //push return addy back onto stack cuz thats how windows has it 
     JMP DWORD ptr fs:[0xc0]; //call with correct stackframe (i think) 
     mov ecx, numparams; //store num params 
     imul ecx, 4; //multiply numparams by sizeof(int) 
     add esp, ecx; //add to esp 
     ret; 
    }; 
} 

Mọi trợ giúp sẽ được đánh giá cao.

+1

Tại sao-oh-tại sao bạn muốn làm điều đó mà không cần viết trình điều khiển? –

Trả lời

2

Hàm callGate mới của bạn không thiết lập khung ngăn xếp bạn muốn, địa chỉ trả về ở đầu ngăn xếp là địa chỉ trả về của cuộc gọi không phải là lệnh sau cuộc gọi.

Đây là những gì chồng trông giống như sau lệnh CALL được thực hiện trong ví dụ của bạn ZwCreateThreadEx từ Windows 8.1:

  • địa chỉ trả lại (retn 0x2c hướng dẫn)
  • địa chỉ trả lại (gọi của ZwCreateThreadEx)
  • đối số (11 DWORD)

Đây là những gì ngăn xếp trông giống như sau khi lệnh JMP được thực hiện trong hàm callGate mới của bạn :

  • trở lại địa chỉ (gọi của callGate)
  • luận

Có những vấn đề khác có chức năng callGate mới của bạn. Nó lưu các giá trị trong các biến toàn cầu có nghĩa là bạn không phải là chức năng thread an toàn. Hai chủ đề không thể gọi callBack cùng một lúc mà không truy cập các giá trị đã lưu này. Nó sử dụng lắp ráp nội tuyến mà cả hai làm cho mã của bạn phức tạp hơn mà nó cần phải được và làm cho nó phụ thuộc vào hành vi không có giấy tờ: làm thế nào trình biên dịch sẽ thiết lập ngăn xếp cho các chức năng.

Đây là cách tôi viết của bạn phiên bản Windows 8.1 của callGate trong MASM:

_text SEGMENT 

MAXARGS = 16 

do_call MACRO argcount 
@@call&argcount: 
    call DWORD PTR fs:[0C0h] 
    ret argcount * 4 
    ENDM 

call_table_entry MACRO argcount 
    DD OFFSET @@call&argcount 
    ENDM 

_callGate PROC 

    pop edx  ; return address 
    pop eax  ; id 
    pop ecx  ; numparams 
    push edx  ; return address 

    cmp ecx, MAXARGS 
    jg @@fail 

    jmp [@@call_table + ecx * 4] 

@@args = 0 
    REPT MAXARGS + 1 
     do_call %@@args 
    @@args = @@args + 1 
    ENDM 

@@fail: 
    ; add better error handling 
    int 3 
    jmp @@fail 

@@call_table: 
@@args = 0 
    REPT MAXARGS + 1 
     call_table_entry %@@args 
    @@args = @@args + 1 
    ENDM 


_callGate ENDP 

_TEXT ENDS 

    END 

thực hiện này được giới hạn MAXARGS đối số (thay đổi giá trị nếu có hệ thống gọi của Windows phải mất hơn 16 đối số). Nó sử dụng các macro tạo ra một bảng các khối mã CALL/RET để tránh phải lưu trữ số lượng đối số ở đâu đó trong suốt cuộc gọi.Tôi có một phiên bản hỗ trợ bất kỳ số lượng các đối số nhưng nó phức tạp hơn và một chút công bằng chậm hơn. Triển khai này chưa được kiểm tra, tôi không có Windows 8.1.

+0

Tôi biết nó nói không để lại bình luận chỉ để nói lời cảm ơn, nhưng tôi đặc biệt muốn quay lại và cảm ơn vì mã của bạn mở ý tưởng của một bảng retn với tôi, do đó cho phép tôi viết điều này: http: // pastebin. com/PBHTd5E9 – applecider

Các vấn đề liên quan