Advertisement
Guest User

Untitled

a guest
Mar 30th, 2017
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.19 KB | None | 0 0
  1. unit PatchInt64Multiplication;
  2.  
  3. interface
  4.  
  5. implementation
  6.  
  7. {$IF Defined(MSWINDOWS) and not Defined(CPUX64)}
  8. uses
  9. SysUtils,
  10. Windows;
  11.  
  12. function GetActualAddr(Proc: Pointer): Pointer;
  13. type
  14. PAbsoluteIndirectJmp = ^TAbsoluteIndirectJmp;
  15. TAbsoluteIndirectJmp = packed record
  16. OpCode: Word;
  17. Addr: PPointer;
  18. end;
  19. begin
  20. Result := Proc;
  21. if (Proc <> nil) and (PAbsoluteIndirectJmp(Proc).OpCode = $25FF) then
  22. Result := PAbsoluteIndirectJmp(Proc).Addr^;
  23. end;
  24.  
  25. procedure RedirectFunction(OrgProc, NewProc: Pointer);
  26. type
  27. TJmpBuffer = packed record
  28. Jmp: Byte;
  29. Offset: Integer;
  30. end;
  31. var
  32. n: UINT_PTR;
  33. JmpBuffer: TJmpBuffer;
  34. begin
  35. JmpBuffer.Jmp := $E9;
  36. JmpBuffer.Offset := PByte(NewProc) - (PByte(OrgProc) + 5);
  37. if not WriteProcessMemory(GetCurrentProcess, OrgProc, @JmpBuffer, SizeOf(JmpBuffer), n) then
  38. RaiseLastOSError;
  39. end;
  40.  
  41. procedure __llmulo_patch;
  42. asm
  43. test edx, edx {Param1-Hi = 0?}
  44. jne @@Large {No, More than one multiply may be needed}
  45. cmp edx, [esp+8] {Param2-Hi = 0?}
  46. jne @@Large {No, More than one multiply may be needed}
  47. mul dword ptr [esp+4] {Only one multiply needed, Set Result}
  48. and eax, eax {Clear Overflow Flag}
  49. ret 8
  50. @@Large:
  51. sub esp, 28 {allocate local storage}
  52. mov [esp], ebx {save used registers}
  53. mov [esp+4], esi
  54. mov [esp+8], edi
  55. mov [esp+12], ebp
  56. mov ebx, [esp+32] {Param2-Lo}
  57. mov ecx, [esp+36] {Param2-Hi}
  58. mov esi, edx
  59. mov edi, ecx
  60. sar esi, 31
  61. sar edi, 31
  62. xor eax, esi
  63. xor edx, esi
  64. sub eax, esi
  65. sbb edx, esi {edx:eax (a1:a0) = abs(Param1)}
  66. xor ebx, edi
  67. xor ecx, edi
  68. sub ebx, edi
  69. sbb ecx, edi {ecx:ebx (b1:b0) = abs(Param2)}
  70. xor esi, edi {Sign Flag, 0 if Params have same sign else -1}
  71. mov [esp+16], eax {a0}
  72. mov [esp+20], edx {a1}
  73. mov [esp+24], ecx {b1}
  74. mul ebx {edx:eax (c1:c0) = a0*b0}
  75. xchg ebx, edx {ebx = c1, edx = b0}
  76. mov edi, eax {abs(Result-Lo) = c0}
  77. xor ecx, ecx {Upper 32 bits of 128 bit result}
  78. xor ebp, ebp {Second 32 bits of 128 bit result}
  79. mov eax, [esp+20] {a1}
  80. mul edx {edx:eax (d1:d0) = a1*b0}
  81. add ebx, eax {c1 + d0}
  82. adc ebp, edx {d1 + carry}
  83. adc ecx, 0 {Possible carry into Upper 32 bits}
  84. mov eax, [esp+16] {a0}
  85. mov edx, [esp+24] {b1}
  86. mul edx {edx:eax (e1:e0) = a0*b1}
  87. add ebx, eax {abs(Result-Hi) = c1 + d0 + e0}
  88. adc ebp, edx {d1 + e1 + carry}
  89. adc ecx, 0 {Possible carry into Upper 32 bits}
  90. mov eax, [esp+20] {a1}
  91. mov edx, [esp+24] {b1}
  92. mul edx {edx:eax (f1:f0) = a1*b1}
  93. add ebp, eax {d1 + e1 + f0 + carry}
  94. adc ecx, edx {f1 + carry}
  95. or ecx, ebp {Overflow if ecx <> 0 or ebp <> 0}
  96. jnz @@Overflow
  97. mov edx, ebx {Set abs(Result-Hi)}
  98. mov eax, edi {Set abs(Result-Lo)}
  99. cmp edx, $80000000
  100. jae @@CheckRange {Possible Overflow if edx>=$80000000}
  101. @@SetSign:
  102. xor eax, esi {Correct Sign of Result}
  103. xor edx, esi
  104. sub eax, esi
  105. sbb edx, esi
  106. mov ebx, [esp] {restore used registers}
  107. mov esi, [esp+4]
  108. mov edi, [esp+8]
  109. mov ebp, [esp+12]
  110. add esp, 28 {Clears Overflow flag}
  111. ret 8
  112. @@CheckRange:
  113. jne @@Overflow {Overflow if edx>$80000000}
  114. test esi, esi {edx=$80000000, Is Sign Flag=0?}
  115. jnz @@SetSign {No, Result is Ok (-MaxInt64)}
  116. @@Overflow:
  117. mov ebx, [esp] {restore used registers}
  118. mov esi, [esp+4]
  119. mov edi, [esp+8]
  120. mov ebp, [esp+12]
  121. add esp, 28
  122. mov ecx, $80000000
  123. dec ecx {Set Overflow Flag}
  124. ret 8
  125. end;
  126.  
  127. function GetSystem__llmulo: Pointer;
  128. asm
  129. mov eax,offset System.@_llmulo
  130. end;
  131.  
  132. procedure PatchIt;
  133. begin
  134. RedirectFunction(GetActualAddr(GetSystem__llmulo), @__llmulo_patch);
  135. end;
  136.  
  137. initialization
  138. PatchIt;
  139. {$IFEND}
  140.  
  141. end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement