Skip to content

Commit 3bd8f4e

Browse files
Charlie Bartozmodem
authored andcommitted
[sanitizer][asan][msvc] Teach GetInstructionSize about many instructions that appear in MSVC generated code. (#69490)
MSVC can sometimes generate instructions in function prologues that asan previously didn't know the size of. This teaches asan those sizes. This isn't super useful for using ASAN with non-msvc compilers, but it does stand alone. From https://reviews.llvm.org/D151008
1 parent 2d26fc8 commit 3bd8f4e

File tree

1 file changed

+122
-21
lines changed

1 file changed

+122
-21
lines changed

compiler-rt/lib/interception/interception_win.cpp

Lines changed: 122 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,11 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
521521
case 0x6A: // 6A XX = push XX
522522
return 2;
523523

524+
// This instruction can be encoded with a 16-bit immediate but that is
525+
// incredibly unlikely.
526+
case 0x68: // 68 XX XX XX XX : push imm32
527+
return 5;
528+
524529
case 0xb8: // b8 XX XX XX XX : mov eax, XX XX XX XX
525530
case 0xB9: // b9 XX XX XX XX : mov ecx, XX XX XX XX
526531
return 5;
@@ -558,6 +563,9 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
558563
case 0xC033: // 33 C0 : xor eax, eax
559564
case 0xC933: // 33 C9 : xor ecx, ecx
560565
case 0xD233: // 33 D2 : xor edx, edx
566+
case 0xDB84: // 84 DB : test bl,bl
567+
case 0xC984: // 84 C9 : test cl,cl
568+
case 0xD284: // 84 D2 : test dl,dl
561569
return 2;
562570

563571
// Cannot overwrite control-instruction. Return 0 to indicate failure.
@@ -566,6 +574,9 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
566574
}
567575

568576
switch (0x00FFFFFF & *(u32*)address) {
577+
case 0xF8E483: // 83 E4 F8 : and esp, 0xFFFFFFF8
578+
case 0x64EC83: // 83 EC 64 : sub esp, 64h
579+
return 3;
569580
case 0x24A48D: // 8D A4 24 XX XX XX XX : lea esp, [esp + XX XX XX XX]
570581
return 7;
571582
}
@@ -580,6 +591,21 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
580591
case 0xA1: // A1 XX XX XX XX XX XX XX XX :
581592
// movabs eax, dword ptr ds:[XXXXXXXX]
582593
return 9;
594+
case 0xF2:
595+
switch (*(u32 *)(address + 1)) {
596+
case 0x2444110f: // f2 0f 11 44 24 XX movsd QWORD PTR
597+
// [rsp + XX], xmm0
598+
case 0x244c110f: // f2 0f 11 4c 24 XX movsd QWORD PTR
599+
// [rsp + XX], xmm1
600+
case 0x2454110f: // f2 0f 11 54 24 XX movsd QWORD PTR
601+
// [rsp + XX], xmm2
602+
case 0x245c110f: // f2 0f 11 5c 24 XX movsd QWORD PTR
603+
// [rsp + XX], xmm3
604+
case 0x2464110f: // f2 0f 11 64 24 XX movsd QWORD PTR
605+
// [rsp + XX], xmm4
606+
return 6;
607+
}
608+
break;
583609

584610
case 0x83:
585611
const u8 next_byte = *(u8*)(address + 1);
@@ -609,50 +635,121 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
609635
return 2;
610636

611637
case 0x058A: // 8A 05 XX XX XX XX : mov al, byte ptr [XX XX XX XX]
638+
case 0x7E80: // 80 7E YY XX cmp BYTE PTR [rsi+YY], XX
639+
case 0x7D80: // 80 7D YY XX cmp BYTE PTR [rbp+YY], XX
640+
case 0x7A80: // 80 7A YY XX cmp BYTE PTR [rdx+YY], XX
641+
case 0x7880: // 80 78 YY XX cmp BYTE PTR [rax+YY], XX
642+
case 0x7B80: // 80 7B YY XX cmp BYTE PTR [rbx+YY], XX
643+
case 0x7980: // 80 79 YY XX cmp BYTE ptr [rcx+YY], XX
644+
return 4;
645+
612646
case 0x058B: // 8B 05 XX XX XX XX : mov eax, dword ptr [XX XX XX XX]
613647
if (rel_offset)
614648
*rel_offset = 2;
615649
return 6;
650+
651+
case 0x7E81: // 81 7E YY XX XX XX XX cmp DWORD PTR [rsi+YY], XX XX XX XX
652+
case 0x7D81: // 81 7D YY XX XX XX XX cmp DWORD PTR [rbp+YY], XX XX XX XX
653+
case 0x7A81: // 81 7A YY XX XX XX XX cmp DWORD PTR [rdx+YY], XX XX XX XX
654+
case 0x7881: // 81 78 YY XX XX XX XX cmp DWORD PTR [rax+YY], XX XX XX XX
655+
case 0x7B81: // 81 7B YY XX XX XX XX cmp DWORD PTR [rbx+YY], XX XX XX XX
656+
case 0x7981: // 81 79 YY XX XX XX XX cmp dword ptr [rcx+YY], XX XX XX XX
657+
return 7;
616658
}
617659

618660
switch (0x00FFFFFF & *(u32*)address) {
619-
case 0xe58948: // 48 8b c4 : mov rbp, rsp
620-
case 0xc18b48: // 48 8b c1 : mov rax, rcx
621-
case 0xc48b48: // 48 8b c4 : mov rax, rsp
622-
case 0xd9f748: // 48 f7 d9 : neg rcx
623-
case 0xd12b48: // 48 2b d1 : sub rdx, rcx
624661
case 0x07c1f6: // f6 c1 07 : test cl, 0x7
625-
case 0xc98548: // 48 85 C9 : test rcx, rcx
626-
case 0xd28548: // 48 85 d2 : test rdx, rdx
662+
case 0x10b70f: // 0f b7 10 : movzx edx, WORD PTR [rax]
663+
case 0xc00b4d: // 4d 0b c0 : or r8, r8
664+
case 0xc03345: // 45 33 c0 : xor r8d, r8d
665+
case 0xc08548: // 48 85 c0 : test rax, rax
627666
case 0xc0854d: // 4d 85 c0 : test r8, r8
667+
case 0xc08b41: // 41 8b c0 : mov eax, r8d
668+
case 0xc0ff48: // 48 ff c0 : inc rax
669+
case 0xc0ff49: // 49 ff c0 : inc r8
670+
case 0xc18b41: // 41 8b c1 : mov eax, r9d
671+
case 0xc18b48: // 48 8b c1 : mov rax, rcx
672+
case 0xc18b4c: // 4c 8b c1 : mov r8, rcx
673+
case 0xc1ff48: // 48 ff c1 : inc rcx
674+
case 0xc1ff49: // 49 ff c1 : inc r9
675+
case 0xc28b41: // 41 8b c2 : mov eax, r10d
628676
case 0xc2b60f: // 0f b6 c2 : movzx eax, dl
629-
case 0xc03345: // 45 33 c0 : xor r8d, r8d
677+
case 0xc2ff48: // 48 ff c2 : inc rdx
678+
case 0xc2ff49: // 49 ff c2 : inc r10
679+
case 0xc38b41: // 41 8b c3 : mov eax, r11d
680+
case 0xc3ff48: // 48 ff c3 : inc rbx
681+
case 0xc3ff49: // 49 ff c3 : inc r11
682+
case 0xc48b41: // 41 8b c4 : mov eax, r12d
683+
case 0xc48b48: // 48 8b c4 : mov rax, rsp
684+
case 0xc4ff49: // 49 ff c4 : inc r12
685+
case 0xc5ff49: // 49 ff c5 : inc r13
686+
case 0xc6ff48: // 48 ff c6 : inc rsi
687+
case 0xc6ff49: // 49 ff c6 : inc r14
688+
case 0xc7ff48: // 48 ff c7 : inc rdi
689+
case 0xc7ff49: // 49 ff c7 : inc r15
630690
case 0xc93345: // 45 33 c9 : xor r9d, r9d
631-
case 0xdb3345: // 45 33 DB : xor r11d, r11d
632-
case 0xd98b4c: // 4c 8b d9 : mov r11, rcx
633-
case 0xd28b4c: // 4c 8b d2 : mov r10, rdx
634-
case 0xc98b4c: // 4C 8B C9 : mov r9, rcx
635-
case 0xc18b4c: // 4C 8B C1 : mov r8, rcx
636-
case 0xd2b60f: // 0f b6 d2 : movzx edx, dl
691+
case 0xc98548: // 48 85 c9 : test rcx, rcx
692+
case 0xc9854d: // 4d 85 c9 : test r9, r9
693+
case 0xc98b4c: // 4c 8b c9 : mov r9, rcx
637694
case 0xca2b48: // 48 2b ca : sub rcx, rdx
638695
case 0xca3b48: // 48 3b ca : cmp rcx, rdx
639-
case 0x10b70f: // 0f b7 10 : movzx edx, WORD PTR [rax]
640-
case 0xc00b4d: // 3d 0b c0 : or r8, r8
641-
case 0xc08b41: // 41 8b c0 : mov eax, r8d
696+
case 0xd12b48: // 48 2b d1 : sub rdx, rcx
642697
case 0xd18b48: // 48 8b d1 : mov rdx, rcx
643-
case 0xdc8b4c: // 4c 8b dc : mov r11, rsp
644698
case 0xd18b4c: // 4c 8b d1 : mov r10, rcx
645-
case 0xE0E483: // 83 E4 E0 : and esp, 0xFFFFFFE0
699+
case 0xd28548: // 48 85 d2 : test rdx, rdx
700+
case 0xd2854d: // 4d 85 d2 : test r10, r10
701+
case 0xd28b4c: // 4c 8b d2 : mov r10, rdx
702+
case 0xd2b60f: // 0f b6 d2 : movzx edx, dl
703+
case 0xd98b4c: // 4c 8b d9 : mov r11, rcx
704+
case 0xd9f748: // 48 f7 d9 : neg rcx
705+
case 0xdb3345: // 45 33 db : xor r11d, r11d
706+
case 0xdb8548: // 48 85 db : test rbx, rbx
707+
case 0xdb854d: // 4d 85 db : test r11, r11
708+
case 0xdc8b4c: // 4c 8b dc : mov r11, rsp
709+
case 0xe0e483: // 83 e4 e0 : and esp, 0xFFFFFFE0
710+
case 0xe48548: // 48 85 e4 : test rsp, rsp
711+
case 0xe4854d: // 4d 85 e4 : test r12, r12
712+
case 0xe58948: // 48 89 e5 : mov rbp, rsp
713+
case 0xed8548: // 48 85 ed : test rbp, rbp
714+
case 0xed854d: // 4d 85 ed : test r13, r13
715+
case 0xf6854d: // 4d 85 f6 : test r14, r14
716+
case 0xff854d: // 4d 85 ff : test r15, r15
646717
return 3;
647718

719+
case 0x245489: // 89 54 24 XX : mov DWORD PTR[rsp + XX], edx
720+
case 0x428d44: // 44 8d 42 XX : lea r8d , [rdx + XX]
721+
case 0x588948: // 48 89 58 XX : mov QWORD PTR[rax + XX], rbx
648722
case 0xec8348: // 48 83 ec XX : sub rsp, XX
649723
case 0xf88349: // 49 83 f8 XX : cmp r8, XX
650-
case 0x588948: // 48 89 58 XX : mov QWORD PTR[rax + XX], rbx
651724
return 4;
652725

726+
case 0x246483: // 83 64 24 XX YY : and DWORD PTR [rsp+XX], YY
727+
return 5;
728+
729+
case 0x788166: // 66 81 78 XX YY YY cmp WORD PTR [rax+XX], YY YY
730+
case 0x798166: // 66 81 79 XX YY YY cmp WORD PTR [rcx+XX], YY YY
731+
case 0x7a8166: // 66 81 7a XX YY YY cmp WORD PTR [rdx+XX], YY YY
732+
case 0x7b8166: // 66 81 7b XX YY YY cmp WORD PTR [rbx+XX], YY YY
733+
case 0x7e8166: // 66 81 7e XX YY YY cmp WORD PTR [rsi+XX], YY YY
734+
case 0x7f8166: // 66 81 7f XX YY YY cmp WORD PTR [rdi+XX], YY YY
735+
return 6;
736+
653737
case 0xec8148: // 48 81 EC XX XX XX XX : sub rsp, XXXXXXXX
654738
return 7;
655739

740+
// clang-format off
741+
case 0x788141: // 41 81 78 XX YY YY YY YY : cmp DWORD PTR [r8+YY], XX XX XX XX
742+
case 0x798141: // 41 81 79 XX YY YY YY YY : cmp DWORD PTR [r9+YY], XX XX XX XX
743+
case 0x7a8141: // 41 81 7a XX YY YY YY YY : cmp DWORD PTR [r10+YY], XX XX XX XX
744+
case 0x7b8141: // 41 81 7b XX YY YY YY YY : cmp DWORD PTR [r11+YY], XX XX XX XX
745+
case 0x7c8141: // 41 81 7c XX YY YY YY YY : cmp DWORD PTR [r12+YY], XX XX XX XX
746+
case 0x7d8141: // 41 81 7d XX YY YY YY YY : cmp DWORD PTR [r13+YY], XX XX XX XX
747+
case 0x7e8141: // 41 81 7e XX YY YY YY YY : cmp DWORD PTR [r14+YY], XX XX XX XX
748+
case 0x7f8141: // 41 81 7f YY XX XX XX XX : cmp DWORD PTR [r15+YY], XX XX XX XX
749+
case 0x247c81: // 81 7c 24 YY XX XX XX XX : cmp DWORD PTR [rsp+YY], XX XX XX XX
750+
return 8;
751+
// clang-format on
752+
656753
case 0x058b48: // 48 8b 05 XX XX XX XX :
657754
// mov rax, QWORD PTR [rip + XXXXXXXX]
658755
case 0x058d48: // 48 8d 05 XX XX XX XX :
@@ -680,8 +777,11 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
680777
case 0x24548948: // 48 89 54 24 XX : mov QWORD PTR [rsp + XX], rdx
681778
case 0x244c894c: // 4c 89 4c 24 XX : mov QWORD PTR [rsp + XX], r9
682779
case 0x2444894c: // 4c 89 44 24 XX : mov QWORD PTR [rsp + XX], r8
780+
case 0x244c8944: // 44 89 4c 24 XX mov DWORD PTR [rsp + XX], r9d
781+
case 0x24448944: // 44 89 44 24 XX mov DWORD PTR [rsp + XX], r8d
782+
case 0x246c8d48: // 48 8d 6c 24 XX : lea rbp, [rsp + XX]
683783
return 5;
684-
case 0x24648348: // 48 83 64 24 XX : and QWORD PTR [rsp + XX], YY
784+
case 0x24648348: // 48 83 64 24 XX YY : and QWORD PTR [rsp + XX], YY
685785
return 6;
686786
}
687787

@@ -695,6 +795,7 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
695795
case 0x458B: // 8B 45 XX : mov eax, dword ptr [ebp + XX]
696796
case 0x5D8B: // 8B 5D XX : mov ebx, dword ptr [ebp + XX]
697797
case 0x7D8B: // 8B 7D XX : mov edi, dword ptr [ebp + XX]
798+
case 0x758B: // 8B 75 XX : mov esi, dword ptr [ebp + XX]
698799
case 0xEC83: // 83 EC XX : sub esp, XX
699800
case 0x75FF: // FF 75 XX : push dword ptr [ebp + XX]
700801
return 3;

0 commit comments

Comments
 (0)