Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

128 lines
2.8 KiB

  1. /*
  2. * xlat.c
  3. *
  4. * Translate
  5. */
  6. #include "decoder.h"
  7. void NEAR init_decoder_translation(t_decoder_context *context)
  8. {
  9. context->dec_instr_pos = 0;
  10. }
  11. #ifdef ASM_TRANSLATE_E8
  12. ulong asm_decoder_translate_e8(ulong instr_pos, ulong file_size, byte *mem, long bytes);
  13. void NEAR decoder_translate_e8(t_decoder_context *context, byte *mem, long bytes)
  14. {
  15. /*
  16. * We don't want the ASM code to have to worry about where in the
  17. * context structure a particular element is
  18. */
  19. context->dec_instr_pos = asm_decoder_translate_e8(
  20. context->dec_instr_pos,
  21. context->dec_current_file_size,
  22. mem,
  23. bytes
  24. );
  25. }
  26. #else /* !ASM_TRANSLATE_E8 */
  27. void NEAR decoder_translate_e8(t_decoder_context *context, byte *mem, long bytes)
  28. {
  29. ulong end_instr_pos;
  30. byte temp[6];
  31. byte *mem_backup;
  32. if (bytes <= 6)
  33. {
  34. context->dec_instr_pos += bytes;
  35. return;
  36. }
  37. mem_backup = mem;
  38. /* backup these bytes */
  39. memcpy(temp, &mem[bytes-6], 6);
  40. /* overwrite them with 0xE8 */
  41. memset(&mem[bytes-6], 0xE8, 6);
  42. end_instr_pos = context->dec_instr_pos + bytes - 6;
  43. while (1)
  44. {
  45. unsigned long absolute;
  46. #if !defined(_X86_)
  47. unsigned long offset;
  48. #endif
  49. /*
  50. * We are guaranteed to hit one of the 6 0xE8's we stuck at the
  51. * end of the buffer, even if we ran into some corrupted data
  52. * that resulted in our jumping over 5 bytes due to a translation
  53. */
  54. while (*mem++ != 0xE8)
  55. context->dec_instr_pos++;
  56. if (context->dec_instr_pos >= end_instr_pos)
  57. break;
  58. /*
  59. * There are 5 or more bytes in the buffer
  60. * (i.e. E8 xx xx xx xx)
  61. *
  62. * We have a complete offset available to (potentially) translate
  63. */
  64. #if defined(_X86_)
  65. absolute = *(ulong *) mem;
  66. #else
  67. absolute = ( (ulong)mem[0]) |
  68. (((ulong)mem[1])<<8) |
  69. (((ulong)mem[2])<<16)|
  70. (((ulong)mem[3])<<24);
  71. #endif
  72. if (absolute < context->dec_current_file_size)
  73. {
  74. /* absolute >= 0 && absolute < dec_current_file_size */
  75. #if defined(_X86_)
  76. *(ulong *) mem = absolute - context->dec_instr_pos;
  77. #else
  78. offset = absolute - context->dec_instr_pos;
  79. mem[0] = (byte) (offset & 255);
  80. mem[1] = (byte) ((offset >> 8) & 255);
  81. mem[2] = (byte) ((offset >> 16) & 255);
  82. mem[3] = (byte) ((offset >> 24) & 255);
  83. #endif
  84. }
  85. else if ((ulong) (-(long) absolute) <= context->dec_instr_pos)
  86. {
  87. /* absolute >= -instr_pos && absolute < 0 */
  88. #if defined(_X86_)
  89. *(ulong *) mem = absolute + context->dec_current_file_size;
  90. #else
  91. offset = absolute + context->dec_current_file_size;
  92. mem[0] = (byte) (offset & 255);
  93. mem[1] = (byte) (offset >> 8) & 255;
  94. mem[2] = (byte) (offset >> 16) & 255;
  95. mem[3] = (byte) (offset >> 24) & 255;
  96. #endif
  97. }
  98. mem += 4;
  99. context->dec_instr_pos += 5;
  100. }
  101. context->dec_instr_pos = end_instr_pos + 6;
  102. /* restore these bytes */
  103. memcpy(&mem_backup[bytes-6], temp, 6);
  104. }
  105. #endif