Привет. В ядре 10 на ISR: KiRaiseSecurityCheckFailure KiRaiseAssertion KiDebugServiceTrap Есть чудо код, зачем это сделано загадка, я даже не могу предположить Код (Text): .text:000000014041010B loc_14041010B: .text:000000014041010B add rsp, 8 .text:000000014041010F call loc_140410102 .text:0000000140410114 .text:0000000140410114 loc_140410114: .text:0000000140410114 add rsp, 8 .text:0000000140410118 call loc_14041010B .text:000000014041011D .text:000000014041011D loc_14041011D: .text:000000014041011D add rsp, 8 .text:0000000140410121 call loc_140410114 Может у кого есть догадки.
TrashGen, При запрещённых прерываниях.. Для задержки сделали бы цикл со счётчиком, тем более эта часть ядра писана на асм. Если бы реализовано как макрос, то вызовы были бы последовательны.
Ahimov, А можно код целиком в файле или граф из ida. Что-то мне подсказывает, что между этими call есть еще что-то или они расположены не последовательно. Во всяком случае разница вот тут немного не сходится с алгоритмом: Код (Text): text:000000014041010B loc_14041010B: .text:000000014041010B add rsp, 8 .text:000000014041010F call loc_140410102 ; эта точка явно выше чем метка до этого call .text:0000000140410114 .text:0000000140410114 loc_140410114: .text:0000000140410114 add rsp, 8 .text:0000000140410118 call loc_14041010B .text:000000014041011D .text:000000014041011D loc_14041011D: .text:000000014041011D add rsp, 8 .text:0000000140410121 call loc_140410114 т.е. изначально код выглядел вот так Код (ASM): @1: ; loc_140410102 add rsp, 8 ret @2: ; loc_14041010B add rsp, 8 call @1 @3: ; loc_140410114 add rsp, 8 call @2 @4: ; ... ...
MaKsIm, Код (Text): .text:000000014040FDB1 loc_14040FDB1: ; CODE XREF: KiRaiseAssertion+13E↓p .text:000000014040FDB1 add rsp, 8 .text:000000014040FDB5 call loc_14040FEC8 .text:000000014040FDBA .text:000000014040FDBA loc_14040FDBA: ; CODE XREF: KiRaiseAssertion+147↓p .text:000000014040FDBA add rsp, 8 .text:000000014040FDBE call loc_14040FDB1 .text:000000014040FDC3 .text:000000014040FDC3 loc_14040FDC3: ; CODE XREF: KiRaiseAssertion+150↓p .text:000000014040FDC3 add rsp, 8 .text:000000014040FDC7 call loc_14040FDBA .text:000000014040FDCC .text:000000014040FDCC loc_14040FDCC: ; CODE XREF: KiRaiseAssertion+159↓p .text:000000014040FDCC add rsp, 8 .text:000000014040FDD0 call loc_14040FDC3 .text:000000014040FDD5 .text:000000014040FDD5 loc_14040FDD5: ; CODE XREF: KiRaiseAssertion+162↓p .text:000000014040FDD5 add rsp, 8 .text:000000014040FDD9 call loc_14040FDCC .text:000000014040FDDE .text:000000014040FDDE loc_14040FDDE: ; CODE XREF: KiRaiseAssertion+16B↓p .text:000000014040FDDE add rsp, 8 .text:000000014040FDE2 call loc_14040FDD5 .text:000000014040FDE7 .text:000000014040FDE7 loc_14040FDE7: ; CODE XREF: KiRaiseAssertion+174↓p .text:000000014040FDE7 add rsp, 8 .text:000000014040FDEB call loc_14040FDDE .text:000000014040FDF0 .text:000000014040FDF0 loc_14040FDF0: ; CODE XREF: KiRaiseAssertion+17D↓p .text:000000014040FDF0 add rsp, 8 .text:000000014040FDF4 call loc_14040FDE7 .text:000000014040FDF9 .text:000000014040FDF9 loc_14040FDF9: ; CODE XREF: KiRaiseAssertion+186↓p .text:000000014040FDF9 add rsp, 8 .text:000000014040FDFD call loc_14040FDF0 .text:000000014040FE02 .text:000000014040FE02 loc_14040FE02: ; CODE XREF: KiRaiseAssertion+18F↓p .text:000000014040FE02 add rsp, 8 .text:000000014040FE06 call loc_14040FDF9 .text:000000014040FE0B .text:000000014040FE0B loc_14040FE0B: ; CODE XREF: KiRaiseAssertion+198↓p .text:000000014040FE0B add rsp, 8 .text:000000014040FE0F call loc_14040FE02 .text:000000014040FE14 .text:000000014040FE14 loc_14040FE14: ; CODE XREF: KiRaiseAssertion+1A1↓p .text:000000014040FE14 add rsp, 8 .text:000000014040FE18 call loc_14040FE0B .text:000000014040FE1D .text:000000014040FE1D loc_14040FE1D: ; CODE XREF: KiRaiseAssertion+1AA↓p .text:000000014040FE1D add rsp, 8 .text:000000014040FE21 call loc_14040FE14 .text:000000014040FE26 .text:000000014040FE26 loc_14040FE26: ; CODE XREF: KiRaiseAssertion+1B3↓p .text:000000014040FE26 add rsp, 8 .text:000000014040FE2A call loc_14040FE1D .text:000000014040FE2F .text:000000014040FE2F loc_14040FE2F: ; CODE XREF: KiRaiseAssertion+1BC↓p .text:000000014040FE2F add rsp, 8 .text:000000014040FE33 call loc_14040FE26 .text:000000014040FE38 .text:000000014040FE38 loc_14040FE38: ; CODE XREF: KiRaiseAssertion+1C5↓p .text:000000014040FE38 add rsp, 8 .text:000000014040FE3C call loc_14040FE2F .text:000000014040FE41 .text:000000014040FE41 loc_14040FE41: ; CODE XREF: KiRaiseAssertion+1CE↓p .text:000000014040FE41 add rsp, 8 .text:000000014040FE45 call loc_14040FE38 .text:000000014040FE4A .text:000000014040FE4A loc_14040FE4A: ; CODE XREF: KiRaiseAssertion+1D7↓p .text:000000014040FE4A add rsp, 8 .text:000000014040FE4E call loc_14040FE41 .text:000000014040FE53 .text:000000014040FE53 loc_14040FE53: ; CODE XREF: KiRaiseAssertion+1E0↓p .text:000000014040FE53 add rsp, 8 .text:000000014040FE57 call loc_14040FE4A .text:000000014040FE5C .text:000000014040FE5C loc_14040FE5C: ; CODE XREF: KiRaiseAssertion+1E9↓p .text:000000014040FE5C add rsp, 8 .text:000000014040FE60 call loc_14040FE53 .text:000000014040FE65 .text:000000014040FE65 loc_14040FE65: ; CODE XREF: KiRaiseAssertion+1F2↓p .text:000000014040FE65 add rsp, 8 .text:000000014040FE69 call loc_14040FE5C .text:000000014040FE6E .text:000000014040FE6E loc_14040FE6E: ; CODE XREF: KiRaiseAssertion+1FB↓p .text:000000014040FE6E add rsp, 8 .text:000000014040FE72 call loc_14040FE65 .text:000000014040FE77 .text:000000014040FE77 loc_14040FE77: ; CODE XREF: KiRaiseAssertion+204↓p .text:000000014040FE77 add rsp, 8 .text:000000014040FE7B call loc_14040FE6E .text:000000014040FE80 .text:000000014040FE80 loc_14040FE80: ; CODE XREF: KiRaiseAssertion+20D↓p .text:000000014040FE80 add rsp, 8 .text:000000014040FE84 call loc_14040FE77 .text:000000014040FE89 .text:000000014040FE89 loc_14040FE89: ; CODE XREF: KiRaiseAssertion+216↓p .text:000000014040FE89 add rsp, 8 .text:000000014040FE8D call loc_14040FE80 .text:000000014040FE92 .text:000000014040FE92 loc_14040FE92: ; CODE XREF: KiRaiseAssertion+21F↓p .text:000000014040FE92 add rsp, 8 .text:000000014040FE96 call loc_14040FE89 .text:000000014040FE9B .text:000000014040FE9B loc_14040FE9B: ; CODE XREF: KiRaiseAssertion+228↓p .text:000000014040FE9B add rsp, 8 .text:000000014040FE9F call loc_14040FE92 .text:000000014040FEA4 .text:000000014040FEA4 loc_14040FEA4: ; CODE XREF: KiRaiseAssertion+231↓p .text:000000014040FEA4 add rsp, 8 .text:000000014040FEA8 call loc_14040FE9B .text:000000014040FEAD .text:000000014040FEAD loc_14040FEAD: ; CODE XREF: KiRaiseAssertion+23A↓p .text:000000014040FEAD add rsp, 8 .text:000000014040FEB1 call loc_14040FEA4 .text:000000014040FEB6 .text:000000014040FEB6 loc_14040FEB6: ; CODE XREF: KiRaiseAssertion+243↓p .text:000000014040FEB6 add rsp, 8 .text:000000014040FEBA call loc_14040FEAD .text:000000014040FEBF .text:000000014040FEBF loc_14040FEBF: ; CODE XREF: KiRaiseAssertion+12C↑p .text:000000014040FEBF add rsp, 8 .text:000000014040FEC3 call loc_14040FEB6 .text:000000014040FEC8 .text:000000014040FEC8 loc_14040FEC8: ; CODE XREF: KiRaiseAssertion+135↑p .text:000000014040FEC8 add rsp, 8 Таких конструкций очень много где, но в этом случае прерывания выключены, тоесть в задержках нет никакого смысла.
Это не все --- Сообщение объединено, 1 май 2025 --- Может дело не в задержках. Допустим надо обнулить кеш кода или еще что-то связанное с аппаратными особенностями процессоров.
Начало это вход в прерывание, что там происходит мы не поймём, так как не известны структуры. Код (Text): .text:000000014040FC80 KiRaiseAssertion proc near ; CODE XREF: KiRaiseAssertionShadow+69↓j .text:000000014040FC80 ; KiRaiseAssertionShadow+71↓j .text:000000014040FC80 ; DATA XREF: ... .text:000000014040FC80 .text:000000014040FC80 var_E8 = byte ptr 0 .text:000000014040FC80 var_s4 = dword ptr 4 .text:000000014040FC80 arg_0 = word ptr 8 .text:000000014040FC80 .text:000000014040FC80 sub qword ptr [rsp+var_E8], 2 .text:000000014040FC85 cmp [rsp+arg_0], 23h ; '#' .text:000000014040FC8B jnz short loc_14040FC92 .text:000000014040FC8D and [rsp+var_s4], 0 .text:000000014040FC92 .text:000000014040FC92 loc_14040FC92: ; CODE XREF: KiRaiseAssertion+B↑j .text:000000014040FC92 sub rsp, 8 .text:000000014040FC96 push rbp .text:000000014040FC97 sub rsp, 158h .text:000000014040FC9E lea rbp, [rsp+80h] .text:000000014040FCA6 mov byte ptr [rbp-55h], 1 .text:000000014040FCAA mov [rbp-50h], rax .text:000000014040FCAE mov [rbp-48h], rcx .text:000000014040FCB2 mov [rbp-40h], rdx .text:000000014040FCB6 mov [rbp-38h], r8 .text:000000014040FCBA mov [rbp-30h], r9 .text:000000014040FCBE mov [rbp-28h], r10 .text:000000014040FCC2 mov [rbp-20h], r11 .text:000000014040FCC6 test byte ptr [rbp+0F0h], 1 .text:000000014040FCCD jnz short loc_14040FCFC .text:000000014040FCCF lfence .text:000000014040FCD2 test byte ptr gs:278h, 1 .text:000000014040FCDB jnz short loc_14040FCE5 .text:000000014040FCDD lfence .text:000000014040FCE0 jmp loc_14040FF3B .text:000000014040FCE5 ; --------------------------------------------------------------------------- .text:000000014040FCE5 .text:000000014040FCE5 loc_14040FCE5: ; CODE XREF: KiRaiseAssertion+5B↑j .text:000000014040FCE5 movzx eax, byte ptr gs:27Ah .text:000000014040FCEE mov ecx, 48h ; 'H' .text:000000014040FCF3 xor edx, edx .text:000000014040FCF5 wrmsr .text:000000014040FCF7 jmp loc_14040FF3B .text:000000014040FCFC ; --------------------------------------------------------------------------- .text:000000014040FCFC .text:000000014040FCFC loc_14040FCFC: ; CODE XREF: KiRaiseAssertion+4D↑j .text:000000014040FCFC test cs:KiKvaShadow, 1 .text:000000014040FD03 jnz short loc_14040FD08 .text:000000014040FD05 swapgs .text:000000014040FD08 .text:000000014040FD08 loc_14040FD08: ; CODE XREF: KiRaiseAssertion+83↑j .text:000000014040FD08 lfence .text:000000014040FD0B mov r10, gs:188h .text:000000014040FD14 mov rcx, gs:188h .text:000000014040FD1D mov rcx, [rcx+220h] .text:000000014040FD24 mov rcx, [rcx+9E0h] .text:000000014040FD2B mov gs:270h, rcx .text:000000014040FD34 mov cl, gs:850h .text:000000014040FD3C mov gs:851h, cl .text:000000014040FD44 mov cl, gs:278h .text:000000014040FD4C mov gs:852h, cl .text:000000014040FD54 movzx eax, byte ptr gs:27Bh .text:000000014040FD5D cmp gs:27Ah, al .text:000000014040FD65 jz short loc_14040FD78 .text:000000014040FD67 mov gs:27Ah, al .text:000000014040FD6F mov ecx, 48h ; 'H' .text:000000014040FD74 xor edx, edx .text:000000014040FD76 wrmsr .text:000000014040FD78 .text:000000014040FD78 loc_14040FD78: ; CODE XREF: KiRaiseAssertion+E5↑j .text:000000014040FD78 movzx edx, byte ptr gs:278h .text:000000014040FD81 test edx, 8 .text:000000014040FD87 jz short loc_14040FDA0 .text:000000014040FD89 mov eax, 1 .text:000000014040FD8E xor edx, edx .text:000000014040FD90 mov ecx, 49h ; 'I' .text:000000014040FD95 wrmsr .text:000000014040FD97 movzx edx, byte ptr gs:278h .text:000000014040FDA0 .text:000000014040FDA0 loc_14040FDA0: ; CODE XREF: KiRaiseAssertion+107↑j .text:000000014040FDA0 test edx, 2 .text:000000014040FDA6 jz loc_14040FED1 .text:000000014040FDAC call loc_14040FEBF .text:000000014040FDB1 .text:000000014040FDB1 loc_14040FDB1: ; CODE XREF: KiRaiseAssertion+13E↓p .text:000000014040FDB1 add rsp, 8 .text:000000014040FDB5 call loc_14040FEC8
Вот лучше просто откройте graphview от ida и сохраните эту процедуру в файле чем такие куски разгребать
MaKsIm, Что и как сохранить ? Кстати в отрисованном графе чушь какая то. Тоесть call ..EBF, а стрелка на блок ..DB1. Глюки иды наверно.
Нет. Там каждая метка достижима двумя путями. По возврату из call, на которую ida рисует стрелку и по вызову. Стрелка по вызову в ida для call не отображается. Т.к. это код ядра, тогда надо рассматривать все состояния всех аппаратных структур памяти во всех режимах. Что, скажем, будет в стеке и теневом стеке TSS, после прерывания трассировки?
MaKsIm, Это просто последовательность call - del_ret - call - del_ret... тоесть никаких скрытых особенностей нет, что один call - del_ret, что их 30..
Ну вот поэтому то и надо хотя бы целиком прочитать код, а не пытаться догадываться о его сути по паре команд.
MaKsIm, Вот вся процедура. --- Сообщение объединено, 1 май 2025 --- Если разметить, что бы было наглядно: Код (Text): call L1 L0: loc_14040FDB1: add rsp, 8 call L2 L3: add rsp, 8 call L0 L4: loc_14040FDC3: add rsp, 8 call L3 L5: add rsp, 8 call L4 L6: add rsp, 8 call L5 L7: add rsp, 8 call L6 L8: add rsp, 8 call L7 L9: add rsp, 8 call L8 L10: add rsp, 8 call L9 L11: add rsp, 8 call L10 L12: add rsp, 8 call L11 L13: add rsp, 8 call L12 L14: add rsp, 8 call L13 L15: add rsp, 8 call L14 L16: add rsp, 8 call L15 L17: add rsp, 8 call L16 L18: add rsp, 8 call L17 L19: add rsp, 8 call L18 L20: add rsp, 8 call L19 add rsp, 8 call L20 ... LX: add rsp, 8 call .. L1: add rsp, 8 call LX L2: add rsp, 8 () Получается последовательность L1 LX L20 L19 ... L3 L0 L2 Макрос это, управление снизу вверх идёт линейно.
Тут если просто попробовать разобраться в том, что происходит, то можно на долго запутаться. У вас команда call имеет в данном случае вот такую реализацию Код (Text): IF near call THEN IF near relative call THEN IF OperandSize = 64 THEN tempDEST := SignExtend(DEST); (* DEST is rel32 *) tempRIP := RIP + tempDEST; IF stack not large enough for a 8-byte return address # это не очень интересно. стек у нас выравнен THEN #SS(0); FI; Push(RIP); # вот тут вот сохранение адреса возврата, которые компенсируются add rsp, 8 IF ShadowStackEnabled(CPL) AND DEST != 0 # а вот это надо бы проверить ShadowStackPush8B(RIP); # и тогда в TSS будут адреса возврата очищать этот самый ShadowStack т.к. add rsp, 8 не будет иметь на него действия FI; RIP := tempRIP; # ну и собственно сам переход на новую инструкцию FI; ... Это все из IntelSDM vol2 Chapter 3 (3-3 Instructions A-L) CALL - Call procedure Но вот зачем их расположили в обратном порядке следования адресов я пока не понял. Возможно это как-то связано с кешем кода. --- Сообщение объединено, 1 май 2025 --- ADD: При этом я вам не просто так сказал про то, что каждая метка достижима двумя путями. Т.е. процессор имея конвейер команд будет паразитно выполнять call XXX (5 байт); add rsp, 8 (4 байта); call XXY (5 байт). Итого 14 байт, что забило бы конвейер Pentium, но у современного процессора он может быть и длиннее. Вот эти инструкции будут выполнены после выполнения RIP := tempRIP хотя их результат и будет аннулирован. Вот что дадут и эти инструкции тоже. Хотя, не исключаю, что это может быть уходом в сторону и не стоит лезть в эти дебри. На эти рассуждения просто подталкивает команда lfence встречающаяся в коде.
MaKsIm, А зачем в прерывании с ядерным стеком защита от rop, тем более что стек такой(dpc) начинается с начала ? Какой вообще смысл в последовательности, быстрее будет без неё конечно.
Вот в том то и дело, что надо разбираться. А это может быть не быстро. Надо анализировать не просто алгоритм на уровне команд, а глубже - на уровне микрокода и железа. Вот что породит куча паразитных вычислений, из-за которых процессор будет постоянно чистить конвейер от холостых инструкций. Ведь код зачем то же разместили в обратном порядке. --- Сообщение объединено, 1 май 2025 --- Что по этому поводу ответил GigaChat --- Сообщение объединено, 1 май 2025 --- И вот еще --- Сообщение объединено, 1 май 2025 --- В двух словах - он не знает
Короче я понял зачем это. У всех векторов в IDT, сервисного шлюза есть эта серия. И одинаков это код: Код (Text): .text:0000000140405581 mov eax, 1 .text:0000000140405586 xor edx, edx .text:0000000140405588 mov ecx, 49h ; 'I' .text:000000014040558D wrmsr .text:000000014040558F .text:000000014040558F loc_14040558F: ; CODE XREF: KiIpiInterrupt+4BF↑j .text:000000014040558F btr word ptr gs:278h, 5 .text:000000014040559A jnb loc_1404056C5 .text:00000001404055A0 call loc_1404056B3 .text:00000001404055A5 .text:00000001404055A5 loc_1404055A5: ; CODE XREF: KiIpiInterrupt+4F2↓p .text:00000001404055A5 add rsp, 8 .text:00000001404055A9 call loc_1404056BC Speculation Control IBPB (MSR 049h) - вот и запись в регистр 1. Другой вопрос что даёт серия.
Вот только у вас тут нету indirect. Indirect это call qword ptr [mem] или call rax. А тут вполне себе явные вызовы. Я просто не видел упоминания, что call rel32 для x86_64, когда rel32 прибавляется к rip это indirect call. Даже по алгоритму инструкции call это явный вызов.
Даже если это так, тогда зачем оно в FindWindow? Она же не обрабатывает прерывания. Это обычная функция пользовательского режима.