Code Monkey home page Code Monkey logo

Comments (6)

stevemk14ebr avatar stevemk14ebr commented on August 11, 2024

Hi this should be supported, but it seems there may be a bug. The issue is that the call is very early in the prologue:

00007FFA69484260 | 48:83EC 28               | sub rsp,28                                                   | kernel32::BindIoCompletionCallback
00007FFA69484264 | 48:FF15 BDEB0500         | call qword ptr ds:[<&RtlSetIoCompletionCallback>]            |

This call is rewritten by polyhook to point to a jmp target that is capable of redirecting the call from the far away trampoline back to the original location the call would go to. This re-write process can be complex, i'm not sure what may be wrong here.

0000018BB4ACB430 | 48:83EC 28               | sub rsp,28                                                                                                                                                                                             |
0000018BB4ACB434 | 48:FF15 06000000         | call qword ptr ds:[18BB4ACB441]                                                                                                                                                                        |
0000018BB4ACB43B | FF25 46000000            | jmp qword ptr ds:[18BB4ACB487]                                                                                                                                                                         |
0000018BB4ACB441 | FF25 38000000            | jmp qword ptr ds:[18BB4ACB47F]    <--- point call here

Could you debug and determine which instruction faults?

from polyhook_2_0.

randydu avatar randydu commented on August 11, 2024

Here is my detailed debug info:

Before Hooking

00007FF86AC04260 | 48:83EC 28               | sub rsp,28                                                                                                                                                                                             |
00007FF86AC04264 | 48:FF15 BDEB0500         | call qword ptr ds:[<&RtlSetIoCompletionCallback>]                                                                                                                                                      |
00007FF86AC0426B | 0F1F4400 00              | nop dword ptr ds:[rax+rax],eax                                                                                                                                                                         |
00007FF86AC04270 | 85C0                     | test eax,eax                                                                                                                                                                                           |
00007FF86AC04272 | 0F88 24230100            | js kernel32.7FF86AC1659C                                                                                                                                                                               |
00007FF86AC04278 | B8 01000000              | mov eax,1                                                                                                                                                                                              |
00007FF86AC0427D | 48:83C4 28               | add rsp,28                                                                                                                                                                                             |
00007FF86AC04281 | C3                       | ret                                                                                                                                                                                                    |
00007FF86AC04282 | CC                       | int3     

After Hooking

00007FF86AC04260 | FF25 85FFFFFF            | jmp qword ptr ds:[<&int __cdecl MyBindIoCompletionCallback_Impl(void * __ptr64,void (__cdecl*)(unsigned long,unsigned long,struct _OVERLAPPED * __ptr64),unsigned long)>]                      |
00007FF86AC04266 | 66:90                    | nop                                                                                                                                                                                                    |
00007FF86AC04268 | 66:90                    | nop                                                                                                                                                                                                    |
00007FF86AC0426A | 90                       | nop                                                                                                                                                                                                    |
00007FF86AC0426B | 0F1F4400 00              | nop dword ptr ds:[rax+rax],eax                                                                                                                                                                         |
00007FF86AC04270 | 85C0                     | test eax,eax                                                                                                                                                                                           |
00007FF86AC04272 | 0F88 24230100            | js kernel32.7FF86AC1659C                                                                                                                                                                               |
00007FF86AC04278 | B8 01000000              | mov eax,1                                                                                                                                                                                              |
00007FF86AC0427D | 48:83C4 28               | add rsp,28                                                                                                                                                                                             |
00007FF86AC04281 | C3                       | ret                                                                                                                                                                                                    |
0000028816C5B430 | 48:83EC 28               | sub rsp,28                                                                                                                                                                                             |
0000028816C5B434 | 48:FF15 06000000         | call qword ptr ds:[28816C5B441]                                                                                                                                                                        |
0000028816C5B43B | FF25 46000000            | jmp qword ptr ds:[28816C5B487]                                                                                                                                                                         |
0000028816C5B441 | FF25 38000000            | jmp qword ptr ds:[28816C5B47F]                                                                                                                                                                         |
//////////
0000028816C5B47F | 282E                     | sub byte ptr ds:[rsi],ch                                                                                                                                                                               | rsi:"ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ�
0000028816C5B481 | C6                       | ???                                                                                                                                                                                                    |
0000028816C5B482 | 6A F8                    | push FFFFFFFFFFFFFFF8                                                                                                                                                                                  |
0000028816C5B484 | 7F 00                    | jg 28816C5B486                                                                                                                                                                                         |
0000028816C5B486 | 006B 42                  | add byte ptr ds:[rbx+42],ch                                                                                                                                                                            |
0000028816C5B489 | C06A F8 7F               | shr byte ptr ds:[rdx-8],7F                                                                                                                                                                             | rdx-8:std::basic_string<char,std::char_traits<char>,std::allocator<char> >::insert+68
0000028816C5B48D | 0000                     | add byte ptr ds:[rax],al                                                                                                                                                                               |
0000028816C5B48F | FD                       | std                                                                                                                                                                                                    |
0000028816C5B490 | FD                       | std                                                                                                                                                                                                    |
0000028816C5B491 | FD                       | std                                                                                                                                                                                                    |

IAT of kernel32.dll:

00007FF86AC62E28  30 2B D2 6B F8 7F 00 00 60 58 C9 6B F8 7F 00 00  0+Òkø...`XÉkø...  
00007FF86AC62E38  70 BE C1 6B F8 7F 00 00 D0 D8 C8 6B F8 7F 00 00  p¾Ákø...ÐØÈkø...  
00007FF86AC62E48  70 D1 CA 6B F8 7F 00 00 80 1E C9 6B F8 7F 00 00  pÑÊkø.....Ékø...  
00007FF86AC62E58  10 D7 CA 6B F8 7F 00 00 20 06 C7 6B F8 7F 00 00  .×Êkø... .Çkø...  
00007FF86AC62E68  40 E3 CA 6B F8 7F 00 00 90 74 CE 6B F8 7F 00 00  @ãÊkø....tÎkø...  
00007FF86AC62E78  60 76 CE 6B F8 7F 00 00 E0 71 CE 6B F8 7F 00 00  `vÎkø...àqÎkø...  
```                                                                   |

ntdll::RtlSetIoCompletionCallback:

00007FF86BD22B30 | 48:8BC4 | mov rax,rsp |
00007FF86BD22B33 | 48:8958 08 | mov qword ptr ds:[rax+8],rbx |
00007FF86BD22B37 | 48:8970 10 | mov qword ptr ds:[rax+10],rsi
00007FF86BD22B3B | 57 | push rdi
00007FF86BD22B3C | 48:83EC 30 | sub rsp,30 |
00007FF86BD22B40 | 48:8BF2 | mov rsi,rdx
00007FF86BD22B43 | 48:8BF9 | mov rdi,rcx
00007FF86BD22B46 | 48:8360 20 00 | and qword ptr ds:[rax+20],0



My question is, the call d_p [xxxx]:

0000028816C5B434 | 48:FF15 06000000 | call qword ptr ds:[28816C5B441]

will set %eip := [28816C5B441]  which is { FF, 25, 38,00,00,00,CD,CD } or as address 0xCDCD0000003825FF, 
it is an invalid code address and will crash immediately.

Also the code:

0000028816C5B441 | FF25 38000000 | jmp qword ptr ds:[28816C5B47F]

Even it can be executed properly, cannot lead us to the correct target, it needs two levels of dereferences:

 target = * ( * ( 28816C5B47F ) )


[28816C5B47F] ==> 00007FF86AC62E28
[00007FF86AC62E28] ==> 00007FF86BD22B30 (our target ntdll::RtlSetIoCompletionCallback)

from polyhook_2_0.

stevemk14ebr avatar stevemk14ebr commented on August 11, 2024

I'll hopefully find some time to look into this before too long. Thank you for the detailed report I will try to replicate. As far as the jump, the FF25 jump is a bit special as it's indirect. The address it points to is a data address that it dereferences, then it jumps there. It is odd there's two levels of indirection there though, I'd expect a single de-reference. Share the c++ code you are using for this particular hook?

from polyhook_2_0.

randydu avatar randydu commented on August 11, 2024

I've fixed this issue in my forked repository.

Now after the hooking, the trampoline code looks like:

Before hooking

00007FFA69484260 | 48:83EC 28               | sub rsp,28                                                   | kernel32::BindIoCompletionCallback
00007FFA69484264 | 48:FF15 BDEB0500         | call qword ptr ds:[<&RtlSetIoCompletionCallback>]            |
00007FFA6948426B | 0F1F4400 00              | nop dword ptr ds:[rax+rax],eax                               |
00007FFA69484270 | 85C0                     | test eax,eax                                                 |
00007FFA69484272 | 0F88 24230100            | js kernel32.7FFA6949659C                                     |

After hooking

Trampoline code:

0000022A1C7BEDC0 48 83 EC 28          sub         rsp,28h  
0000022A1C7BEDC4 48 FF 15 45 00 00 00 call        qword ptr [22A1C7BEE10h]  
0000022A1C7BEDCB FF 25 47 00 00 00    jmp         qword ptr [22A1C7BEE18h]  
0000022A1C7BEDD1 C0 0F 88             ror         byte ptr [rdi],88h  
0000022A1C7BEDD4 24 23                and         al,23h  

//////// dest holders ////////
0000022A1C7BEE10 30 2B EA 40 FC 7F 00 00 ; => &RtlSetIoCompletionCallback
0000022A1C7BEE18 6B 42 22 3F FC 7F 00 00 ; => & test eax, eax

The CALL instruction only needs a dest-holder to specify its destination.

It is odd there's two levels of indirection there though, I'd expect a single de-reference

Yes, there is a bug here that does not set the indirect flag properly:

(hasGroup(capInst, x86_insn_group::X86_GRP_CALL) && inst.size() >= 3 && inst.getBytes().at(1) == 0xff && inst.getBytes().at(2) == 0x25)

should be:

(hasGroup(capInst, x86_insn_group::X86_GRP_CALL) && inst.size() >= 3 && inst.getBytes().at(1) == 0xff && inst.getBytes().at(2) == 0x15)

the CALL is FF15, not FF25, as a result the PLH::Instruction::getDestionation() does not dereference the correct calling target.

from polyhook_2_0.

stevemk14ebr avatar stevemk14ebr commented on August 11, 2024

Glad you've fixed your issues! You will want to revert your change of 0x25 -> 0x15, the 0x25 case handles an indirect jump. What you want is to introduce a second check for the additional 0x15 indirect call case which you are absolutely correct I do not handle correctly (or like, at all). Thank you for looking into this!

from polyhook_2_0.

stevemk14ebr avatar stevemk14ebr commented on August 11, 2024

This is resolved

from polyhook_2_0.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.