Как правильно биндить релоки?

Тема в разделе "WASM.WIN32", создана пользователем intel_x128, 6 июл 2011.

  1. intel_x128

    intel_x128 New Member

    Публикаций:
    0
    Регистрация:
    17 май 2009
    Сообщения:
    345
    Как определить, где заканчиваются релоки?
    Биндить их до первого нуль-дворда или размер дергать из заголовка.
    Столкнулся с нестандартной ситуацией, когда размер в заголовке один и судя по нему нужно фиксить 8 элементов.
    А нуль-дворд несколько дальше и судя по нему, фиксить нужно 14 элементов.
    Я взял максимум.

    Те, кто реверсил ядро - как релоки обрабатывает система?
     
  2. Sunzer

    Sunzer Member

    Публикаций:
    0
    Регистрация:
    25 май 2008
    Сообщения:
    256
    Код (Text):
    1.  MOV ECX,IMAGE_BASE
    2.  MOV EAX,[ECX+03Ch]
    3.  MOV ECX,[ECX+EAX+0A4h] ; Размер таблицы
    4.  MOV EAX,RELOC_TABLE_ADDR ; Указатель на таблицу релокаций
    5.  
    6.  TEST EAX,EAX
    7.  JE NO_RELOCATIN_TABLE
    8.  ADD EAX,IMAGE_BASE
    9.  MOV EBX,OWN_IMAGE_BASE ; Дельта (NewImageBase-ImageBase)
    10.  SUB EBX,IMAGE_BASE
    11.  NEXT_RELOC_BLOCK: ; Обрабатываем следующий блок
    12.   TEST ECX,ECX
    13.   JE RELOCATION_TABLE_FIX_DONE
    14.   MOV ESI,[EAX]   ; Получаем RVA смещение
    15.   MOV EDI,[EAX+4] ; Получаем размер блока
    16.   SUB ECX,EDI
    17.   SUB EDI,8
    18.   TEST EDI,EDI
    19.   JE NULL_RELOC_BLOCK ; Если блок пустой
    20.   SHR EDI,1
    21.   ADD EAX,8
    22.  NEXT_ITEM:
    23.   MOVZX EDX, WORD PTR DS:[EAX]
    24.   TEST EDX,EDX
    25.   JE RELOC_NULL
    26.   AND DH,0Fh
    27.   ADD EDX,IMAGE_BASE
    28.   ADD EDX,ESI
    29.   SUB [EDX],EBX ; Фиксим адрес
    30.  RELOC_NULL:
    31.   INC EAX
    32.   INC EAX
    33.   DEC EDI
    34.   JNZ NEXT_ITEM ; Обрабатываем следующий эллемент блока
    35.  NULL_RELOC_BLOCK:
    36.  JMP NEXT_RELOC_BLOCK
     
  3. klzlk

    klzlk New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2011
    Сообщения:
    449
    Код (Text):
    1. /*++
    2.  
    3. Copyright (c) Microsoft Corporation. All rights reserved.
    4.  
    5. You may only use this code if you agree to the terms of the Windows Research Kernel Source Code License agreement (see License.txt).
    6. If you do not agree to the terms, do not use the code.
    7.  
    8.  
    9. Module Name:
    10.  
    11.    ldrreloc.c
    12.  
    13. Abstract:
    14.  
    15.     This module contains the code to relocate an image when
    16.     the preferred base isn't available. This is called by the
    17.     boot loader, device driver loader, and system loader.
    18.  
    19. --*/
    20.  
    21. #include "ntrtlp.h"
    22.  
    23. //
    24. // Mark a HIGHADJ entry as needing an increment if reprocessing.
    25. //
    26. #define LDRP_RELOCATION_INCREMENT   0x1
    27.  
    28. //
    29. // Mark a HIGHADJ entry as not suitable for reprocessing.
    30. //
    31. #define LDRP_RELOCATION_FINAL       0x2
    32.  
    33. PIMAGE_BASE_RELOCATION
    34. LdrProcessRelocationBlockLongLong(
    35.     IN ULONG_PTR VA,
    36.     IN ULONG SizeOfBlock,
    37.     IN PUSHORT NextOffset,
    38.     IN LONGLONG Diff
    39.     );
    40.  
    41. #if defined(ALLOC_PRAGMA)
    42. #pragma alloc_text(PAGE,LdrRelocateImage)
    43. #pragma alloc_text(PAGE,LdrRelocateImageWithBias)
    44. #pragma alloc_text(PAGE,LdrProcessRelocationBlock)
    45. #pragma alloc_text(PAGE,LdrProcessRelocationBlockLongLong)
    46. #endif // ALLOC_PRAGMA
    47.  
    48. typedef LDR_RELOCATE_IMAGE_RETURN_TYPE NTSTATUS;
    49.  
    50. LDR_RELOCATE_IMAGE_RETURN_TYPE
    51. LdrRelocateImage (
    52.     __in PVOID NewBase,
    53.     __in PCSTR LoaderName,
    54.     __in LDR_RELOCATE_IMAGE_RETURN_TYPE Success,
    55.     __in LDR_RELOCATE_IMAGE_RETURN_TYPE Conflict,
    56.     __in LDR_RELOCATE_IMAGE_RETURN_TYPE Invalid
    57.     )
    58. /*++
    59.  
    60. Routine Description:
    61.  
    62.     This routine relocates an image file that was not loaded into memory
    63.     at the preferred address.
    64.  
    65. Arguments:
    66.  
    67.     NewBase - Supplies a pointer to the image base.
    68.  
    69.     LoaderName - Indicates which loader routine is being called from.
    70.  
    71.     Success - Value to return if relocation successful.
    72.  
    73.     Conflict - Value to return if can't relocate.
    74.  
    75.     Invalid - Value to return if relocations are invalid.
    76.  
    77. Return Value:
    78.  
    79.     Success if image is relocated.
    80.     Conflict if image can't be relocated.
    81.     Invalid if image contains invalid fixups.
    82.  
    83. --*/
    84.  
    85. {
    86.     //
    87.     // Just call LdrRelocateImageWithBias() with a zero bias.
    88.     //
    89.  
    90.     return LdrRelocateImageWithBias( NewBase,
    91.                                      0,
    92.                                      LoaderName,
    93.                                      Success,
    94.                                      Conflict,
    95.                                      Invalid );
    96. }
    97.  
    98.  
    99. LDR_RELOCATE_IMAGE_RETURN_TYPE
    100. LdrRelocateImageWithBias (
    101.     __in PVOID NewBase,
    102.     __in LONGLONG AdditionalBias,
    103.     __in PCSTR LoaderName,
    104.     __in LDR_RELOCATE_IMAGE_RETURN_TYPE Success,
    105.     __in LDR_RELOCATE_IMAGE_RETURN_TYPE Conflict,
    106.     __in LDR_RELOCATE_IMAGE_RETURN_TYPE Invalid
    107.     )
    108. /*++
    109.  
    110. Routine Description:
    111.  
    112.     This routine relocates an image file that was not loaded into memory
    113.     at the preferred address.
    114.  
    115. Arguments:
    116.  
    117.     NewBase - Supplies a pointer to the image base.
    118.  
    119.     AdditionalBias - An additional quantity to add to all fixups.  The
    120.                      32-bit X86 loader uses this when loading 64-bit images
    121.                      to specify a NewBase that is actually a 64-bit value.
    122.  
    123.     LoaderName - Indicates which loader routine is being called from.
    124.  
    125.     Success - Value to return if relocation successful.
    126.  
    127.     Conflict - Value to return if can't relocate.
    128.  
    129.     Invalid - Value to return if relocations are invalid.
    130.  
    131. Return Value:
    132.  
    133.     Success if image is relocated.
    134.     Conflict if image can't be relocated.
    135.     Invalid if image contains invalid fixups.
    136.  
    137. --*/
    138.  
    139. {
    140.     LONGLONG Diff;
    141.     ULONG TotalCountBytes = 0;
    142.     ULONG_PTR VA;
    143.     ULONGLONG OldBase;
    144.     ULONG SizeOfBlock;
    145.     PUCHAR FixupVA;
    146.     USHORT Offset;
    147.     PUSHORT NextOffset = NULL;
    148.     PIMAGE_NT_HEADERS NtHeaders;
    149.     PIMAGE_BASE_RELOCATION NextBlock;
    150.     LDR_RELOCATE_IMAGE_RETURN_TYPE Status;
    151.  
    152.     RTL_PAGED_CODE();
    153.  
    154.     NtHeaders = RtlImageNtHeader( NewBase );
    155.     if (NtHeaders == NULL) {
    156.         Status = Invalid;
    157.         goto Exit;
    158.     }
    159.  
    160.     switch (NtHeaders->OptionalHeader.Magic) {
    161.        
    162.         case IMAGE_NT_OPTIONAL_HDR32_MAGIC:
    163.  
    164.             OldBase =
    165.                 ((PIMAGE_NT_HEADERS32)NtHeaders)->OptionalHeader.ImageBase;
    166.             break;
    167.  
    168.         case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
    169.  
    170.             OldBase =
    171.                 ((PIMAGE_NT_HEADERS64)NtHeaders)->OptionalHeader.ImageBase;
    172.             break;
    173.  
    174.         default:
    175.  
    176.             Status = Invalid;
    177.             goto Exit;
    178.     }
    179.  
    180.     //
    181.     // Locate the relocation section.
    182.     //
    183.  
    184.     NextBlock = (PIMAGE_BASE_RELOCATION)RtlImageDirectoryEntryToData(
    185.             NewBase, TRUE, IMAGE_DIRECTORY_ENTRY_BASERELOC, &TotalCountBytes);
    186.  
    187.     //
    188.     // It is possible for a file to have no relocations, but the relocations
    189.     // must not have been stripped.
    190.     //
    191.  
    192.     if (!NextBlock || !TotalCountBytes) {
    193.    
    194.         if (NtHeaders->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) {
    195.  
    196. #if DBG
    197.  
    198.             DbgPrint("%s: Image can't be relocated, no fixup information.\n", LoaderName);
    199.  
    200. #endif // DBG
    201.  
    202.             Status = Conflict;
    203.  
    204.         } else {
    205.             Status = Success;
    206.         }
    207.  
    208.         goto Exit;
    209.     }
    210.  
    211.     //
    212.     // If the image has a relocation table, then apply the specified fixup
    213.     // information to the image.
    214.     //
    215.     Diff = (ULONG_PTR)NewBase - OldBase + AdditionalBias;
    216.     while (TotalCountBytes) {
    217.         SizeOfBlock = NextBlock->SizeOfBlock;
    218.         TotalCountBytes -= SizeOfBlock;
    219.         SizeOfBlock -= sizeof(IMAGE_BASE_RELOCATION);
    220.         SizeOfBlock /= sizeof(USHORT);
    221.         NextOffset = (PUSHORT)((PCHAR)NextBlock + sizeof(IMAGE_BASE_RELOCATION));
    222.  
    223.         VA = (ULONG_PTR)NewBase + NextBlock->VirtualAddress;
    224.  
    225.         if ( !(NextBlock = LdrProcessRelocationBlockLongLong( VA,
    226.                                                               SizeOfBlock,
    227.                                                               NextOffset,
    228.                                                               Diff)) ) {
    229. #if DBG
    230.             DbgPrint("%s: Unknown base relocation type\n", LoaderName);
    231. #endif
    232.             Status = Invalid;
    233.             goto Exit;
    234.         }
    235.     }
    236.  
    237.     Status = Success;
    238. Exit:
    239.     return Status;
    240. }
    241.  
    242. PIMAGE_BASE_RELOCATION
    243. LdrProcessRelocationBlock(
    244.     IN ULONG_PTR VA,
    245.     IN ULONG SizeOfBlock,
    246.     IN PUSHORT NextOffset,
    247.     IN LONG_PTR Diff
    248.     )
    249. {
    250.     PIMAGE_BASE_RELOCATION baseRelocation;
    251.  
    252.     baseRelocation = LdrProcessRelocationBlockLongLong( VA,
    253.                                                         SizeOfBlock,
    254.                                                         NextOffset,
    255.                                                         (LONGLONG)Diff );
    256.  
    257.     return baseRelocation;
    258. }
    259.  
    260. // begin_rebase
    261. PIMAGE_BASE_RELOCATION
    262. LdrProcessRelocationBlockLongLong(
    263.     IN ULONG_PTR VA,
    264.     IN ULONG SizeOfBlock,
    265.     IN PUSHORT NextOffset,
    266.     IN LONGLONG Diff
    267.     )
    268. {
    269.     PUCHAR FixupVA;
    270.     USHORT Offset;
    271.     LONG Temp;
    272.     ULONG Temp32;
    273.     ULONGLONG Value64;
    274.     LONGLONG Temp64;
    275.  
    276.     RTL_PAGED_CODE();
    277.  
    278.     while (SizeOfBlock--) {
    279.  
    280.        Offset = *NextOffset & (USHORT)0xfff;
    281.        FixupVA = (PUCHAR)(VA + Offset);
    282.  
    283.        //
    284.        // Apply the fixups.
    285.        //
    286.  
    287.        switch ((*NextOffset) >> 12) {
    288.  
    289.             case IMAGE_REL_BASED_HIGHLOW :
    290.                 //
    291.                 // HighLow - (32-bits) relocate the high and low half
    292.                 //      of an address.
    293.                 //
    294.                 *(LONG UNALIGNED *)FixupVA += (ULONG) Diff;
    295.                 break;
    296.  
    297.             case IMAGE_REL_BASED_HIGH :
    298.                 //
    299.                 // High - (16-bits) relocate the high half of an address.
    300.                 //
    301.                 Temp = *(PUSHORT)FixupVA << 16;
    302.                 Temp += (ULONG) Diff;
    303.                 *(PUSHORT)FixupVA = (USHORT)(Temp >> 16);
    304.                 break;
    305.  
    306.             case IMAGE_REL_BASED_HIGHADJ :
    307.                 //
    308.                 // Adjust high - (16-bits) relocate the high half of an
    309.                 //      address and adjust for sign extension of low half.
    310.                 //
    311.  
    312.                 //
    313.                 // If the address has already been relocated then don't
    314.                 // process it again now or information will be lost.
    315.                 //
    316.                 if (Offset & LDRP_RELOCATION_FINAL) {
    317.                     ++NextOffset;
    318.                     --SizeOfBlock;
    319.                     break;
    320.                 }
    321.  
    322.                 Temp = *(PUSHORT)FixupVA << 16;
    323.                 ++NextOffset;
    324.                 --SizeOfBlock;
    325.                 Temp += (LONG)(*(PSHORT)NextOffset);
    326.                 Temp += (ULONG) Diff;
    327.                 Temp += 0x8000;
    328.                 *(PUSHORT)FixupVA = (USHORT)(Temp >> 16);
    329.  
    330.                 break;
    331.  
    332.             case IMAGE_REL_BASED_LOW :
    333.                 //
    334.                 // Low - (16-bit) relocate the low half of an address.
    335.                 //
    336.                 Temp = *(PSHORT)FixupVA;
    337.                 Temp += (ULONG) Diff;
    338.                 *(PUSHORT)FixupVA = (USHORT)Temp;
    339.                 break;
    340.  
    341.             case IMAGE_REL_BASED_IA64_IMM64:
    342.  
    343.                 //
    344.                 // Align it to bundle address before fixing up the
    345.                 // 64-bit immediate value of the movl instruction.
    346.                 //
    347.  
    348.                 FixupVA = (PUCHAR)((ULONG_PTR)FixupVA & ~(15));
    349.                 Value64 = (ULONGLONG)0;
    350.  
    351.                 //
    352.                 // Extract the lower 32 bits of IMM64 from bundle
    353.                 //
    354.  
    355.  
    356.                 EXT_IMM64(Value64,
    357.                         (PULONG)FixupVA + EMARCH_ENC_I17_IMM7B_INST_WORD_X,
    358.                         EMARCH_ENC_I17_IMM7B_SIZE_X,
    359.                         EMARCH_ENC_I17_IMM7B_INST_WORD_POS_X,
    360.                         EMARCH_ENC_I17_IMM7B_VAL_POS_X);
    361.                 EXT_IMM64(Value64,
    362.                         (PULONG)FixupVA + EMARCH_ENC_I17_IMM9D_INST_WORD_X,
    363.                         EMARCH_ENC_I17_IMM9D_SIZE_X,
    364.                         EMARCH_ENC_I17_IMM9D_INST_WORD_POS_X,
    365.                         EMARCH_ENC_I17_IMM9D_VAL_POS_X);
    366.                 EXT_IMM64(Value64,
    367.                         (PULONG)FixupVA + EMARCH_ENC_I17_IMM5C_INST_WORD_X,
    368.                         EMARCH_ENC_I17_IMM5C_SIZE_X,
    369.                         EMARCH_ENC_I17_IMM5C_INST_WORD_POS_X,
    370.                         EMARCH_ENC_I17_IMM5C_VAL_POS_X);
    371.                 EXT_IMM64(Value64,
    372.                         (PULONG)FixupVA + EMARCH_ENC_I17_IC_INST_WORD_X,
    373.                         EMARCH_ENC_I17_IC_SIZE_X,
    374.                         EMARCH_ENC_I17_IC_INST_WORD_POS_X,
    375.                         EMARCH_ENC_I17_IC_VAL_POS_X);
    376.                 EXT_IMM64(Value64,
    377.                         (PULONG)FixupVA + EMARCH_ENC_I17_IMM41a_INST_WORD_X,
    378.                         EMARCH_ENC_I17_IMM41a_SIZE_X,
    379.                         EMARCH_ENC_I17_IMM41a_INST_WORD_POS_X,
    380.                         EMARCH_ENC_I17_IMM41a_VAL_POS_X);
    381.  
    382.                 EXT_IMM64(Value64,
    383.                         ((PULONG)FixupVA + EMARCH_ENC_I17_IMM41b_INST_WORD_X),
    384.                         EMARCH_ENC_I17_IMM41b_SIZE_X,
    385.                         EMARCH_ENC_I17_IMM41b_INST_WORD_POS_X,
    386.                         EMARCH_ENC_I17_IMM41b_VAL_POS_X);
    387.                 EXT_IMM64(Value64,
    388.                         ((PULONG)FixupVA + EMARCH_ENC_I17_IMM41c_INST_WORD_X),
    389.                         EMARCH_ENC_I17_IMM41c_SIZE_X,
    390.                         EMARCH_ENC_I17_IMM41c_INST_WORD_POS_X,
    391.                         EMARCH_ENC_I17_IMM41c_VAL_POS_X);
    392.                 EXT_IMM64(Value64,
    393.                         ((PULONG)FixupVA + EMARCH_ENC_I17_SIGN_INST_WORD_X),
    394.                         EMARCH_ENC_I17_SIGN_SIZE_X,
    395.                         EMARCH_ENC_I17_SIGN_INST_WORD_POS_X,
    396.                         EMARCH_ENC_I17_SIGN_VAL_POS_X);
    397.                 //
    398.                 // Update 64-bit address
    399.                 //
    400.  
    401.                 Value64+=Diff;
    402.  
    403.                 //
    404.                 // Insert IMM64 into bundle
    405.                 //
    406.  
    407.                 INS_IMM64(Value64,
    408.                         ((PULONG)FixupVA + EMARCH_ENC_I17_IMM7B_INST_WORD_X),
    409.                         EMARCH_ENC_I17_IMM7B_SIZE_X,
    410.                         EMARCH_ENC_I17_IMM7B_INST_WORD_POS_X,
    411.                         EMARCH_ENC_I17_IMM7B_VAL_POS_X);
    412.                 INS_IMM64(Value64,
    413.                         ((PULONG)FixupVA + EMARCH_ENC_I17_IMM9D_INST_WORD_X),
    414.                         EMARCH_ENC_I17_IMM9D_SIZE_X,
    415.                         EMARCH_ENC_I17_IMM9D_INST_WORD_POS_X,
    416.                         EMARCH_ENC_I17_IMM9D_VAL_POS_X);
    417.                 INS_IMM64(Value64,
    418.                         ((PULONG)FixupVA + EMARCH_ENC_I17_IMM5C_INST_WORD_X),
    419.                         EMARCH_ENC_I17_IMM5C_SIZE_X,
    420.                         EMARCH_ENC_I17_IMM5C_INST_WORD_POS_X,
    421.                         EMARCH_ENC_I17_IMM5C_VAL_POS_X);
    422.                 INS_IMM64(Value64,
    423.                         ((PULONG)FixupVA + EMARCH_ENC_I17_IC_INST_WORD_X),
    424.                         EMARCH_ENC_I17_IC_SIZE_X,
    425.                         EMARCH_ENC_I17_IC_INST_WORD_POS_X,
    426.                         EMARCH_ENC_I17_IC_VAL_POS_X);
    427.                 INS_IMM64(Value64,
    428.                         ((PULONG)FixupVA + EMARCH_ENC_I17_IMM41a_INST_WORD_X),
    429.                         EMARCH_ENC_I17_IMM41a_SIZE_X,
    430.                         EMARCH_ENC_I17_IMM41a_INST_WORD_POS_X,
    431.                         EMARCH_ENC_I17_IMM41a_VAL_POS_X);
    432.                 INS_IMM64(Value64,
    433.                         ((PULONG)FixupVA + EMARCH_ENC_I17_IMM41b_INST_WORD_X),
    434.                         EMARCH_ENC_I17_IMM41b_SIZE_X,
    435.                         EMARCH_ENC_I17_IMM41b_INST_WORD_POS_X,
    436.                         EMARCH_ENC_I17_IMM41b_VAL_POS_X);
    437.                 INS_IMM64(Value64,
    438.                         ((PULONG)FixupVA + EMARCH_ENC_I17_IMM41c_INST_WORD_X),
    439.                         EMARCH_ENC_I17_IMM41c_SIZE_X,
    440.                         EMARCH_ENC_I17_IMM41c_INST_WORD_POS_X,
    441.                         EMARCH_ENC_I17_IMM41c_VAL_POS_X);
    442.                 INS_IMM64(Value64,
    443.                         ((PULONG)FixupVA + EMARCH_ENC_I17_SIGN_INST_WORD_X),
    444.                         EMARCH_ENC_I17_SIGN_SIZE_X,
    445.                         EMARCH_ENC_I17_SIGN_INST_WORD_POS_X,
    446.                         EMARCH_ENC_I17_SIGN_VAL_POS_X);
    447.                 break;
    448.  
    449.             case IMAGE_REL_BASED_DIR64:
    450.  
    451.                 *(ULONGLONG UNALIGNED *)FixupVA += Diff;
    452.  
    453.                 break;
    454.  
    455.             case IMAGE_REL_BASED_MIPS_JMPADDR :
    456.                 //
    457.                 // JumpAddress - (32-bits) relocate a MIPS jump address.
    458.                 //
    459.                 Temp = (*(PULONG)FixupVA & 0x3ffffff) << 2;
    460.                 Temp += (ULONG) Diff;
    461.                 *(PULONG)FixupVA = (*(PULONG)FixupVA & ~0x3ffffff) |
    462.                                                 ((Temp >> 2) & 0x3ffffff);
    463.  
    464.                 break;
    465.  
    466.             case IMAGE_REL_BASED_ABSOLUTE :
    467.                 //
    468.                 // Absolute - no fixup required.
    469.                 //
    470.                 break;
    471.  
    472.             case IMAGE_REL_BASED_SECTION :
    473.                 //
    474.                 // Section Relative reloc.  Ignore for now.
    475.                 //
    476.                 break;
    477.  
    478.             case IMAGE_REL_BASED_REL32 :
    479.                 //
    480.                 // Relative intrasection. Ignore for now.
    481.                 //
    482.                 break;
    483.  
    484.             default :
    485.                 //
    486.                 // Illegal - illegal relocation type.
    487.                 //
    488.  
    489.                 return (PIMAGE_BASE_RELOCATION)NULL;
    490.        }
    491.        ++NextOffset;
    492.     }
    493.     return (PIMAGE_BASE_RELOCATION)NextOffset;
    494. }
    495.  
    496. // end_rebase