1

I have a small command line application named "debugger" which acts as a debugger for a process A. Now this application works fine with x86 and x64. Now I have to migrate this "debugger" to ARM64 architecture. What this debugger very briefly does is attach breakpoints aka writes instruction int3(0xcc) to the start of functions it finds in the map file of the Process A. Now whenever I try to run my application via this "debugger" app I am able to set breakpoints but the app continuously gets "access_violation". My hunch is that for ARM64 architecture the instruction "0xcc" which I am writing to the start of the functions is causing the access_violation. Now I have two questions:

  1. Is "0xcc" valid instruction for putting breakpoint in ARM64?
  2. Can writing "0xcc" in ARM64 cause access_violation?

Please provide links for your answers as well.

Edit 2: Used "BRK" instead of "0xcc"

int BP_INSTRUCTION_OPCODE_ARM = 0x000020D4;
void * baseAddress = "Some Value";
mProcessHandle = "ProcessHandle";
SIZE_T NumBytesWritten;
::WriteProcessMemory(mProcessHandle, baseAddress, (void*)&BP_INSTRUCTION_OPCODE_ARM, sizeof(int), &NumBytesWritten);

This did not work for me... Am I doing something wrong here?

After disassembling the DebugBreak() function I got the below assembly code. From this I tried to write the instruction 0x150 as breakpoint but I am still getting EXCEPTION_ACCESS_VIOLATION.

    126:    DebugBreak();
00007FF7141C1884 90000128             adrp        x8,__imp_SetSecurityDescriptorDacl (07FF7141E5000h)  
00007FF7141C1888 F940A908             ldr         x8,[x8,#0x150]  
00007FF7141C188C D63F0100             blr         x8
  • 1
    1. [No](https://stackoverflow.com/questions/11345371/how-do-i-set-a-software-breakpoint-on-an-arm-processor/22393106); 2. [Yes](https://learn.microsoft.com/en-us/windows-hardware/drivers/debugger/debug-privilege) and [more info](http://webpages.eng.wayne.edu/~fy8421/paper/nailgun-sp19.pdf). – Eljay Nov 16 '21 at 16:18
  • @Eljay Thanks a lot for your answer. I tried to convert the assembly instruction "BKPT" to hexadecimal so that I can write it to process memory. I used the following tool - https://armconverter.com/ , this says "BKPT" is invalid for ARM64. Is the instruction different for ARM64? – arielBodyLotion Nov 16 '21 at 16:41
  • 1
    Looks like the [ARM64](https://developer.arm.com/documentation/102120/0100/Debug-exceptions) used `BRK`. – Eljay Nov 16 '21 at 17:20
  • @Eljay I have updated the post with the code I used. Using BRK as opcode did not solve the issue for me. Is there anything wrong with my implementation? – arielBodyLotion Nov 16 '21 at 17:56
  • @Eljay My doubts are firstly is the hex conversion of BRK correct and secondly can we write integer values in the process Memory? – arielBodyLotion Nov 16 '21 at 18:23
  • Why not just disassemble the `DebugBreak` function on an `arm64` system to see what the breakpoint opcode's encoding is? – Raymond Chen Nov 16 '21 at 18:24
  • The third argument to `WriteProcessMemory` is supposed to be a *pointer* to the data to be written, not the data itself converted to a pointer. So you want `&BP_INSTRUCTION_OPCODE_ARM` instead of `(void *)BP_INSTRUCTION_OPCODE_ARM`. – Nate Eldredge Nov 16 '21 at 18:34
  • @NateEldredge Sorry I forgot the ampersand. I am actually doing `(void*)&BP_INSTRUCTION_OPCODE_ARM` and it is still not working. – arielBodyLotion Nov 16 '21 at 18:50
  • Then my best guess would be that your base address is wrong. How are you computing it? Also, do you test whether `WriteProcessMemory` succeeded? – Nate Eldredge Nov 16 '21 at 18:52
  • @NateEldredge `WriteProcessMemory` return true. The base address code seems to be correct because it is the same code used for x86 and x64. I am still a little iffy about the code I have written for setting breakpoint in ARM64. For getting base path I use `CurEvent.u.CreateProcessInfo.lpBaseOfImage` I get a CreateProcess event from process A which then gives me the base path. – arielBodyLotion Nov 16 '21 at 19:01
  • you could try to put `udf` instruction instead. Trying to execute `udf` cause `Undefined Instruction exception`. So if you get one than your writing is likely to be correct and exception handler likely to dump error address as well. `e7f000f1 udf #1` – user3124812 Nov 17 '21 at 04:20
  • I am unable to convert `UDF #1` for ARM64, I thing there is a problem with the tool I am using to convert instructions to hex - https://armconverter.com/ . This is because udf is defined for ARM64 - https://developer.arm.com/documentation/ddi0602/2021-09/Base-Instructions/UDF--Permanently-Undefined-?lang=en .Anyone know of a better tool? – arielBodyLotion Nov 17 '21 at 07:56
  • @RaymondChen can you please elaborate a bit on your approach. I think my opcode to hex conversion wrong. I want to know what "number" should I write to the process memory which is correct for breakpoint instruction. – arielBodyLotion Nov 17 '21 at 17:25
  • Write a test amd64 app that calls `DebugBreak()`. Step into the `DebugBreak()` function. Dump the bytes to see how the opcode is encoded. – Raymond Chen Nov 17 '21 at 20:28
  • @RaymondChen I am not able to step into the DebugBreak() function, when I step in it just says app.exe has triggered a breakpoint. Is there some setting I need to turn on to step into the function? – arielBodyLotion Dec 20 '21 at 10:04
  • Then just disassemble the function. (It sounds like you are doing source level debugging. Switch to assembly since that's what you want to see. Also turn off "Just My Code" since you want to step into somebody else's code.) – Raymond Chen Dec 20 '21 at 17:23
  • @RaymondChen I tried your advice. Kindly see the latest edit to my question. Am I doing things correctly? – arielBodyLotion Dec 21 '21 at 17:55
  • Can anyone tell me an instruction I can write which does not have any impact on the code execution. I want to make sure that only the instruction I am writing is incorrect and nothing else is the problem. @Eljay . Please help. – arielBodyLotion Dec 21 '21 at 18:02
  • Have you tried looking at any ARM64 open source debuggers? – Eljay Dec 21 '21 at 18:15
  • Yes I tried but did not find anything fruitful there, closest I came to find something was - https://github.com/x64dbg/x64dbg . This is for x86 and x64 only. – arielBodyLotion Dec 21 '21 at 18:24
  • This is your code that is **calling** DebugBreak. You have to step into the `blr` to get to the actual `DebugBreak` function. – Raymond Chen Dec 21 '21 at 18:41

0 Answers0