Architecture and Register (R*X) Differences
Over time, many 64-bit architectures have been introduced. The first to be supported by Windows, Itanium, was designed for performance computing and was not compatible with x86. AMD later introduced a 64-bit architecture called AMD64, which was compatible with x86 code. Intel adopted AMD64 and called its implementation EM64T. This architecture is now known as x64, or x86-64, and it is the most popular implementation of 64-bit code on Windows
https://software.intel.com/en-us/articles/introduction-to-x64-assembly
For 64-bit programming, the general-purpose registers are RAX, RBX, RCX, RDX, RBP, RSI, RDI, and RSP:
RAX (addressable as EAX/AX/AH/AL) plays the standard role of an
accumulator. It is also used as the placeholder for the return value
of a function call. All registers of this set are addressable in a
32/16/8-bit size as well.
RBX plays the standard role of base indexing during memory access.
RCX is normally used as a counter.
RDX is normally used for data operations during division and data type
extensions using EAX during multiplication in tandem.
RBP is normally used as a base pointer.
RDI is used as the destination index.
RSI is used as the source index.
RSP is the stack pointer.
There are 8 more general-purpose registers that can be used anyway: R8, R9, R10, R11, R12, R13, R14, and R15.
x64 also supports instruction pointer–relative data addressing. This is an important difference between x64 and x86 in relation to PIC and shellcode. Specifically, in x86 assembly, anytime you want to access data at a location that is not an offset from a register, the instruction must store the entire address. This is called absolute addressing. But in x64 assembly, you can access data at a location that is an offset from the current instruction pointer. The x64 literature refers to this as RIP-relative addressing.
There is also some major differences in the Calling Conventions used by major Operating Systems under a 64-bit architecture. Check the books, Practical Malware Analysis (Chapter 21 on 64-Bit Malware) and Gray Hat Hacking: The Ethical Hacker's Handbook, 4th Edition (Chapter 22 on Analyzing 64-bit Malware) for full details.
PE32 vs. PE32+ Differences
The PE format, which was originally designed for 32 bits, had to undergo some minor changes. The new format that supports 64-bit Windows is called PE32+ (sometimes people refer to it as PE64 -- they are interchangeable; they are the same thing). No new fields were added, so structurally the two formats are still the same, with the modifications listed here:
Malware/Rootkit Differences (e.g., in the meterpreter implant)
Windows
The primary incentive for malware to be compiled as a 64-bit binary is the ability to inject code into other 64-bit processes and load kernel drivers that have to be 64-bit executables.
Injections techniques will not work when you are trying to inject a DLL from 64-bit processes into 32-bit processes or vice versa, due to the Windows-on-Windows for 64-bit (WoW64) kernel. Specifically, 64-bit processes require pointers that are 64 bits so the pointer we passed to CreateRemoteThread()
for LoadLibrary()
would need to be a 64-bit pointer. Because our injection application is 32 bits, we cannot specify a 64-bit pointer. How do you get around this? Have two injection applications—one for 32 bits and one for 64 bits.
Also see these notes on Registry Redirection when dealing with 32-bit EXE Malware on 64-bit Windows systems.
Linux
This infection method was conceived by Silvio Cesare in the late '90s and has since shown up in various Linux viruses, such as Brundle Fly and the POCs produced by Silvio himself. This method is inventive, but it limits the infection payload to one page size. On 32-bit Linux systems, this is 4096 bytes, but on 64-bit systems, the executables use large pages that measure 0x200000 bytes, which allows for about a 2 MB infection. The way that this infection works is by taking advantage of the fact that in memory, there will be one page of padding between the text segment and data segment, whereas on disk, the text and data segments are back to back, but someone can take advantage of the expected space between segments and utilize that as an area for the payload.
In ELF relocation entries, compiled objects for 32-bit use implicit addends while 64-bit tend to use the ElfN_Rela
structs that contain an explicit addend.
Exploitation and Fuzz-Testing Technique Differences
One of the biggest differences is in the size of the memory. Since we have 64-bits, we can only address 47 of these in the user space. This results in a value of 0x4141414141414141 not being able to be used because it is too large, since it takes up all 64 bits; therefore, we can address a value of 0x0000414141414141 and we will be safe.
The other issue with exploit development on 64-bit platforms is that they introduced the NX bit, or Hardware DEP, as well as additional layers of protections. There has been significant research into bypassing NX, SSP and ASLR on 64-bit systems as well as providing more layers for protection against these bypasses. For a prezo on Linux including the ASLR-NG design and implementation, check out -- https://www.blackhat.com/docs/asia-16/materials/asia-16-Marco-Gisbert-Exploiting-Linux-And-PaX-ASLRS-Weaknesses-On-32-And-64-Bit-Systems.pdf -- and the corresponding whitepaper -- https://www.blackhat.com/docs/asia-16/materials/asia-16-Marco-Gisbert-Exploiting-Linux-And-PaX-ASLRS-Weaknesses-On-32-And-64-Bit-Systems-wp.pdf
It may be more-common for developers to make mistakes with signedness or other issues leading to Integer Overflow attacks as seen in this research -- https://www.coresecurity.com/blog/ms16-039-windows-10-64-bits-integer-overflow-exploitation-by-using-gdi-objects
Tool Differences
Windows
All of the utilities in the PsTools suite work on all supported client and server versions of Windows. Support for 64-bit versions requires that WOW64, the components that support 32-bit applications on 64-bit Windows, be installed. (WOW64 can be uninstalled on Server Core).
In PowerShell, Get-PEHeader
will show PE32 and PE32+ properties.
For WinDbg, you can check the status of 32-bit/64-bit/WOW64 with the .effmach
command. When using 64-bit debugger to generate a dump file for a 32-bit process running on a 64-bit system under WOW64, you will not be able to debug that dump file.
macOS / iOS
class-dump (32-bit) vs. class-dump-z (64-bit)
Tracing Objective-C Method Calls
ARM64
Here is what it looks like to decode system calls on AMD64 platform.
Hexacorn on 64-bit Tools
http://www.hexacorn.com/blog/2014/05/21/rce-list-of-64-bit-tools/
Other Nuances
Heaven's Gate
http://www.hexacorn.com/blog/2015/10/26/heavens-gate-and-a-chameleon-code-x8664/
http://www.alex-ionescu.com/?p=300
Windows x64 Driver Enforcement
http://blog.hackersonlineclub.com/2016/02/tdl-tool-for-bypassing-windows-x64.html
Microsoft Office 64-bit issues such as VBA code modification
http://www.codekabinett.com/rdumps.php?Lang=2&targetDoc=windows-api-declaration-vba-64-bit
http://blog.nektra.com/main/2014/04/23/64-bit-microsoft-office-applications-do-not-like-stack-walking/
Additional Recommendations and Considerations
Highly-recommend a read of Chapter 7 in the book, A Guide to Kernel Exploitation, for more details on 64-bit differences, especially at the kernel and driver layers