From 55a35ce01eb613d222ce646d664d46bfface2aaa Mon Sep 17 00:00:00 2001 From: krystalgamer Date: Thu, 4 Aug 2016 12:24:38 +0100 Subject: [PATCH] Removed my ASM interpreter now using captsone --- asmInterpreter.c | 851 ++++------------------- include/arm.h | 883 ++++++++++++++++++++++++ include/arm64.h | 1154 +++++++++++++++++++++++++++++++ include/capstone.h | 670 ++++++++++++++++++ include/mips.h | 906 ++++++++++++++++++++++++ include/platform.h | 105 +++ include/ppc.h | 1254 ++++++++++++++++++++++++++++++++++ include/sparc.h | 522 ++++++++++++++ include/systemz.h | 832 ++++++++++++++++++++++ include/x86.h | 1630 ++++++++++++++++++++++++++++++++++++++++++++ include/xcore.h | 237 +++++++ resonance.c | 11 +- xor.h | 94 +-- 13 files changed, 8352 insertions(+), 797 deletions(-) create mode 100644 include/arm.h create mode 100644 include/arm64.h create mode 100644 include/capstone.h create mode 100644 include/mips.h create mode 100644 include/platform.h create mode 100644 include/ppc.h create mode 100644 include/sparc.h create mode 100644 include/systemz.h create mode 100644 include/x86.h create mode 100644 include/xcore.h diff --git a/asmInterpreter.c b/asmInterpreter.c index 57c8088..74da020 100644 --- a/asmInterpreter.c +++ b/asmInterpreter.c @@ -1,492 +1,84 @@ #include "xor.h" +#include "include/capstone.h" -void addAsmInstruction(PASM_INSTRUCTION pAsmInstruction, BYTE opcode, BYTE size, BOOL needToFix, BOOL variableSize, BOOL sharedOpcode, BYTE regValue,void* fixSizeFunction){ - - - if(!pAsmInstruction) - return; - - if(pAsmInstruction->next) //Not empty - addAsmInstruction(pAsmInstruction->next, opcode, size, needToFix, variableSize, sharedOpcode,regValue,fixSizeFunction); - else{ - //Initialize it - pAsmInstruction->opcode = opcode; - pAsmInstruction->size = size; - pAsmInstruction->needToFix = needToFix; - pAsmInstruction->variableSize = variableSize; - - pAsmInstruction->sharedOpcode = sharedOpcode; - - pAsmInstruction->regValue = regValue; - pAsmInstruction->defineSize = fixSizeFunction; - - if(!(pAsmInstruction->next = malloc(sizeof(ASM_INSTRUCTION)))) //Couldn't allocate space for the next - return; //RIP - - memset(pAsmInstruction->next, 0, sizeof(ASM_INSTRUCTION)); //clear to avoid problems - - } -} - -/* - BYTE opcode; - BYTE size; - - BOOL needToFix; - BOOL variableSize; - BOOL sharedOpcode; - - BYTE regValue;//Only used if sharedOpcode is used - void (*defineSize)(struct _asmInstruction *pThis);//Only used if variableSize is true - */ -void addAllAsmInstructions(PASM_INSTRUCTION *ppAsmInstruction){ - - DWORD tmp = 0; - *ppAsmInstruction = malloc(sizeof(ASM_INSTRUCTION)); - - if(*ppAsmInstruction == NULL) - exit(1); - - memset(*ppAsmInstruction, 0, sizeof(ASM_INSTRUCTION));//Clear the crap - - #define INC_EAX 0x40 - //All instructions in the middle are 1 byte sized - #define POPAD 0x61 - tmp = INC_EAX; - - while(tmp <= POPAD) - addAsmInstruction(*ppAsmInstruction, tmp++, 1, FALSE, FALSE, FALSE,0,NULL); - - #define PUSH 0x68 - addAsmInstruction(*ppAsmInstruction, PUSH, 5, FALSE, FALSE, FALSE,0,NULL); - //MOV ZONE - #define MOV_01 0x88 - #define MOV_LAST 0x8B - tmp = MOV_01; - - while(tmp <= MOV_LAST) - addAsmInstruction(*ppAsmInstruction, tmp++, 0, FALSE, TRUE, FALSE,0,getMovSize); - - #define MOV_C7 0xC7 - addAsmInstruction(*ppAsmInstruction, MOV_C7, 0, FALSE, TRUE, FALSE,0,getMovSize); - - //SUB ZONE - #define SUB_AL_IMM8 0x2C - #define SUB_EAX_IMM32 (SUB_AL_IMM8 + 1) - tmp = SUB_AL_IMM8; - - while(tmp <= SUB_EAX_IMM32) - addAsmInstruction(*ppAsmInstruction, tmp++, (tmp==SUB_AL_IMM8) ? 2 : 5, FALSE, FALSE, FALSE,0,NULL); - - #define SUB_R8_IMM8 0x80 - #define SUB_R32_IMM32 (SUB_R8_IMM8 + 1) - #define SUB_R32_IMM8 (SUB_R32_IMM32 + 2) - tmp = SUB_R8_IMM8; - - while(tmp<=SUB_R32_IMM8){ - if(tmp == 0x82){//Fuck x86 - tmp++; - continue; - } - addAsmInstruction(*ppAsmInstruction, tmp++, 0, FALSE, TRUE, TRUE,5,getXorSize); - } - - - //OR ZONE - #define OR_01 0x09 - tmp = OR_01; - - while(tmp <= OR_01) - addAsmInstruction(*ppAsmInstruction, tmp++, 0, FALSE, TRUE, FALSE,0,getOrSize); - - //LEAVE & RETN & NOP - - #define LEAVE 0xC9 - #define RETN 0xC3 - #define NOP 0x90 - - addAsmInstruction(*ppAsmInstruction, LEAVE, 1, FALSE, FALSE, FALSE,0,NULL); - addAsmInstruction(*ppAsmInstruction, RETN, 1, FALSE, FALSE, FALSE,0,NULL); - addAsmInstruction(*ppAsmInstruction, NOP, 1, FALSE, FALSE, FALSE,0,NULL); - +BOOL interptFunction(HANDLE hProcess, FUNCTION function){ - //CALL AND JMP ZONE - - #define ABS_NEAR_CALL 0xFF - #define ABS_NEAR_CALL_REG ((2<<3) | (DISPLACEMENT_ONLY)) - #define REL_CALL 0xE8 - - addAsmInstruction(*ppAsmInstruction, REL_CALL, 5, TRUE, FALSE, FALSE,0,NULL); - - #define REL_JMP 0xE9 - #define REL_SHORT_JMP 0xEB - #define ABS_NEAR_JUMP ABS_NEAR_CALL - #define ABS_NEAR_JUMP_REG ((1<<3) | (DISPLACEMENT_ONLY)) - - addAsmInstruction(*ppAsmInstruction, REL_JMP, 5, TRUE, FALSE, FALSE,0,NULL); - addAsmInstruction(*ppAsmInstruction, REL_SHORT_JMP, 2, TRUE, FALSE, FALSE,0,NULL); - - //MOV TODO - addAsmInstruction(*ppAsmInstruction, 0xB8, 5, FALSE, FALSE, FALSE,0,NULL); - - - //TEST ZONE - #define TEST_AL_IMM8 0xA8 - #define TEST_EAX_IMM32 0xA9 - - addAsmInstruction(*ppAsmInstruction, TEST_AL_IMM8, 2, FALSE, FALSE, FALSE,0,NULL); - addAsmInstruction(*ppAsmInstruction, TEST_EAX_IMM32, 5, FALSE, FALSE, FALSE,0,NULL);//they have different sizes :| - - #define TEST_R_IMM8 0xF6 - #define TEST_R_IMM32 0xF7 - tmp = TEST_R_IMM8; - - while(tmp<=TEST_R_IMM32) - addAsmInstruction(*ppAsmInstruction, tmp++, 3, FALSE, TRUE, TRUE,0,getTestSize); - - #define TEST_R_R8 0x84 - #define TEST_R_R32 0x85 - tmp = TEST_R_R8; - - while(tmp<=TEST_R_R32) - addAsmInstruction(*ppAsmInstruction, tmp++, 2, FALSE, TRUE, TRUE,0,getTestSize); - - //XOR ZONE - #define XOR_AL 0x34 - #define XOR_EAX 0x35 - tmp = XOR_AL; - - while(tmp<=XOR_EAX) - addAsmInstruction(*ppAsmInstruction, tmp++, (tmp == XOR_AL) ? 2 : 5, FALSE, TRUE, TRUE,0,NULL); + unsigned char *buffer; + SIZE_T bytesRead = 0; - #define XOR_R8_IMM8 SUB_R8_IMM8 - #define XOR_R32_IMM32 0x81 - #define XOR_R32_IMM8 0x83 - tmp = XOR_R8_IMM8; + if(!(buffer = malloc(function.size))) + return FALSE; - while(tmp<=XOR_R32_IMM8){ - if(tmp == 0x82){//Fuck x86 - tmp++; - continue; - } - addAsmInstruction(*ppAsmInstruction, tmp++, 2, FALSE, TRUE, TRUE,6,getXorSize); + if(!ReadProcessMemory(hProcess, (void*)function.startAddr, buffer, function.size, &bytesRead) && bytesRead != function.size){ + MessageBoxA(NULL, "ReadProcessMemory2 failed!", "FAILED", 0); + return FALSE; } - - //ADD ZONE - #define ADD_AL_IMM8 0x04 - #define ADD_AL_IMM32 0x05 - tmp = ADD_AL_IMM8; - - while(tmp<=ADD_AL_IMM32) - addAsmInstruction(*ppAsmInstruction, tmp++, (tmp == ADD_AL_IMM8) ? 2 : 5, FALSE, FALSE, FALSE,0,NULL); - #define ADD_R8_IMM8 XOR_R8_IMM8 - #define ADD_R32_IMM32 (ADD_R8_IMM8 + 1) - #define ADD_R32_IMM8 (ADD_R32_IMM32 + 2) - tmp = ADD_R8_IMM8; - - while(tmp<=ADD_R32_IMM8){ - if(tmp == 0x82){//Fuck x86 - tmp++; - continue; - } - addAsmInstruction(*ppAsmInstruction, tmp++, 2, FALSE, TRUE, TRUE,0, getXorSize);//Exact same thing so :D - } - -} + csh handle; + cs_insn *insn; + size_t count; + + if (cs_open(CS_ARCH_X86, CS_MODE_32, &handle) != CS_ERR_OK) + return -1; + cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON); - -/* - BYTE opcode; - BYTE size; - BOOL needToFix; - BOOL variableSize; - BOOL sharedOpcode; + count = cs_disasm(handle, buffer, function.size, function.startAddr, 0, &insn); - BYTE regValue;//Only used if sharedOpcode is used - void (*defineSize)(struct _asmInstruction *pThis);//Only used if variableSize is true - */ -void getXorSize(PASM_INSTRUCTION pAsmInstruction, const unsigned char *buffer){ + PABS_INSTRUCTION pAbsInstruction = NULL; + size_t byteCounter = 0; - BYTE tmp = 0; - if(XOR_R8_IMM8 <= buffer[0] && XOR_R32_IMM8 >= buffer[0]){//FUCK 0x82 - - if(buffer[0] == XOR_R8_IMM8 || buffer[0] == XOR_R32_IMM8){ //they share the same opcodes so meh - tmp = (buffer[1] >> 6); - - switch(tmp){ - //easier way than 2 if statements - case REGISTER_ADDRESSING: - DEFAULT_SIZE(3) - break; - case ONE_BYTE_DISPLACEMENT: - DEFAULT_SIZE(4) - SIB_INSTRUCTION - break; - case FOUR_BYTE_DISPLACEMENT: - DEFAULT_SIZE(7) - SIB_INSTRUCTION - break; - case REGISTER_INDIRECT_ADDRESSING: - DEFAULT_SIZE(3) - SIB_AND_DISPLACEMENT_INSTRUCTION - break; - } - - } - else if(buffer[0] == XOR_R32_IMM32){ - tmp = (buffer[1] >> 6); + if (count > 0) { + size_t currIns = 0; + cs_x86 *x86_insn = NULL; - switch(tmp){ - //easier way than 2 if statements - case REGISTER_ADDRESSING: - DEFAULT_SIZE(6) - break; - case ONE_BYTE_DISPLACEMENT: - DEFAULT_SIZE(7) - SIB_INSTRUCTION - break; - case FOUR_BYTE_DISPLACEMENT: - DEFAULT_SIZE(10) - SIB_INSTRUCTION - break; - case REGISTER_INDIRECT_ADDRESSING: - DEFAULT_SIZE(6) - SIB_AND_DISPLACEMENT_INSTRUCTION - break; - } - - } + for (currIns = 0; currIns < count; currIns++) { - } -} - -void getTestSize(PASM_INSTRUCTION pAsmInstruction, const unsigned char *buffer){ - - BYTE tmp = 0; - if(TEST_R_IMM8 <= buffer[0] && TEST_R_IMM32 >= buffer[0]){ - - tmp = (buffer[1] >> 6); - - switch(tmp){ - //easier way than 2 if statements - case REGISTER_ADDRESSING: - DEFAULT_SIZE(3 + ((buffer[0] == TEST_R_IMM32) ? 3 : 0)) - break; - case ONE_BYTE_DISPLACEMENT: - DEFAULT_SIZE(4 + ((buffer[0] == TEST_R_IMM32) ? 3 : 0)) - SIB_INSTRUCTION - break; + if(!strcmp(insn[currIns].mnemonic, "jmp") || !strcmp(insn[currIns].mnemonic, "call")){ - case FOUR_BYTE_DISPLACEMENT: - DEFAULT_SIZE(7 + ((buffer[0] == TEST_R_IMM32) ? 3 : 0)) - SIB_INSTRUCTION - break; - case REGISTER_INDIRECT_ADDRESSING: - DEFAULT_SIZE(3 + ((buffer[0] == TEST_R_IMM32) ? 3 : 0)) - SIB_AND_DISPLACEMENT_INSTRUCTION - break; - } - - } - else if(TEST_R_R8 <= buffer[0] && TEST_R_R32 >= buffer[0]){ - - tmp = (buffer[1] >> 6); - - switch(tmp){ - //easier way than 2 if statements - case REGISTER_ADDRESSING: - DEFAULT_SIZE(2) - break; - case ONE_BYTE_DISPLACEMENT: - DEFAULT_SIZE(3) - SIB_INSTRUCTION - break; - case FOUR_BYTE_DISPLACEMENT: - DEFAULT_SIZE(6) - SIB_INSTRUCTION - break; - case REGISTER_INDIRECT_ADDRESSING: - DEFAULT_SIZE(2) - SIB_AND_DISPLACEMENT_INSTRUCTION - break; - } - - - } -} - -void getMovSize(PASM_INSTRUCTION pAsmInstruction, const unsigned char *buffer){ - - BYTE tmp = 0; - if( MOV_01 <= buffer[0] && MOV_LAST >= buffer[0]){ - - tmp = (buffer[1] >> 6); - - switch(tmp){ - - case REGISTER_ADDRESSING: - DEFAULT_SIZE(2) - break; - case ONE_BYTE_DISPLACEMENT: - DEFAULT_SIZE(3) - break; - case FOUR_BYTE_DISPLACEMENT: - DEFAULT_SIZE(6) - break; - case REGISTER_INDIRECT_ADDRESSING: - DEFAULT_SIZE(2) + x86_insn = &(insn[currIns].detail->x86); - SIB_AND_DISPLACEMENT_INSTRUCTION - - break; - } - - } - else if(buffer[0] == MOV_C7){ - - tmp = ((buffer[1] >> 3) & 7); // get the bits in the the 6,5,4 position - - if(!tmp){ //C7 mov requires reg to be 0 - - tmp = buffer[1] >> 6; - - switch(tmp){ - - case REGISTER_ADDRESSING: - DEFAULT_SIZE(6) - break; - case ONE_BYTE_DISPLACEMENT: - DEFAULT_SIZE(7) - - SIB_INSTRUCTION + if(x86_insn->op_count != 1)//Something went wrong + return FALSE; + + cs_x86_op *operand = &(x86_insn->operands[0]); + + if(operand->type != X86_OP_IMM) + continue; - break; - case FOUR_BYTE_DISPLACEMENT: - DEFAULT_SIZE(10) - SIB_INSTRUCTION + if(operand->imm > function.startAddr + function.size){ - break; - case REGISTER_INDIRECT_ADDRESSING: - DEFAULT_SIZE(6) - SIB_AND_DISPLACEMENT_INSTRUCTION - break; - + if(!fixRelativeJmpOrCall(operand->imm, byteCounter, &pAbsInstruction, insn[currIns].size,strcmp(insn[currIns].mnemonic, "jmp"))) + return FALSE; + + printf("Found one relative jmp/call to fix!\n"); + byteCounter += 6; + } + else + byteCounter += insn[currIns].size; } - + else + byteCounter += insn[currIns].size; } + + cs_free(insn, count); } -} - - -void getOrSize(PASM_INSTRUCTION pAsmInstruction, const unsigned char *buffer){ - - BYTE tmp = 0; - if( OR_01 <= buffer[0] && OR_01 >= buffer[0]){ - - - - tmp = (buffer[1] >> 6); - - switch(tmp){ - - case REGISTER_ADDRESSING: - DEFAULT_SIZE(2) - break; - case ONE_BYTE_DISPLACEMENT: - DEFAULT_SIZE(3) - SIB_INSTRUCTION - break; - - case FOUR_BYTE_DISPLACEMENT: - DEFAULT_SIZE(6) - SIB_INSTRUCTION - break; - case REGISTER_INDIRECT_ADDRESSING: - DEFAULT_SIZE(2) - SIB_AND_DISPLACEMENT_INSTRUCTION - break; - } - - } -} - -void printAsmInstructions(PASM_INSTRUCTION pAsmInstruction){ - - if(!pAsmInstruction) - return; - - printf("%02X %08X\n", pAsmInstruction->opcode, pAsmInstruction->next); + else + printf("ERROR: Failed to disassemble given code!\n"); + + cs_close(&handle); fflush(stdout); - printAsmInstructions(pAsmInstruction->next); -} - -BOOL interptFunction(HANDLE hProcess, FUNCTION function, PASM_INSTRUCTION pAsmInstructionList){ - - unsigned char *buffer; - SIZE_T bytesRead = 0; - - - if(!(buffer = malloc(function.size))) + if(!getAbsoluteAddressStorage(hProcess, pAbsInstruction)) return FALSE; - if(!ReadProcessMemory(hProcess, (void*)function.startAddr, buffer, function.size, &bytesRead) && bytesRead != function.size){ - MessageBoxA(NULL, "ReadProcessMemory2 failed!", "FAILED", 0); - return FALSE; - } - - ASM_INSTRUCTION converted; //The raw function will be stored here - memset(&converted, 0, sizeof(ASM_INSTRUCTION)); + BYTE* newFunction = createNewFunction(buffer, byteCounter, pAbsInstruction); - - if(!analyzeFunction(buffer, function.size,pAsmInstructionList, &converted)) + if(!newFunction) return FALSE; - freeLinkedList((void*)&(pAsmInstructionList->next), sizeof(ASM_INSTRUCTION));//The first is not allocated with malloc - - if(!fixRelativeAddresses(&converted, function, buffer)) - return FALSE; - - - ABS_ADDRESS_STORAGE absAddrStorage; //will be used to fix the absolute addresses - memset(&absAddrStorage, 0, sizeof(ABS_ADDRESS_STORAGE)); - - - - if(!addAbsoluteAddressesToStorage(&converted,&absAddrStorage)) //first add these babies - return FALSE; - - - DWORD convertFunctionSize = getConvertedFunctionSize(&converted); - if(countStorageId(&absAddrStorage)){ //Only do this if there are any - - DWORD tmpCounter = 0; - DWORD addressBuffer = 0; - - if(!(addressBuffer = fixAbsoluteAddresses(&absAddrStorage, &tmpCounter)))//then fix them - return FALSE; - - HANDLE address = VirtualAllocEx(hProcess, NULL, sizeof(DWORD)*tmpCounter, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); - - if(!address) - return FALSE; - - if(!WriteProcessMemory(hProcess, (void*)address, (void*)addressBuffer, tmpCounter*sizeof(DWORD), NULL)) - return FALSE; - - if(!(buffer = (convertFunction(&converted, buffer, convertFunctionSize, (DWORD)address))))//write addressBuffer to memmory - return FALSE; - - } - else{ - if(!(buffer = (convertFunction(&converted, buffer, convertFunctionSize, (DWORD)0))))//no address buffer :D - return FALSE; - } - #define SHELL_SIZE 101 unsigned char sexyShell[SHELL_SIZE] = { 0x60, 0x9C, 0xB9, 0x00, 0x00, 0x00, 0x00, 0x81, 0xF9, 0xFF, 0x00, 0x00, 0x00, 0x75, 0x45, 0xC7, @@ -498,34 +90,34 @@ BOOL interptFunction(HANDLE hProcess, FUNCTION function, PASM_INSTRUCTION pAsmIn 0x25, 0x78, 0x56, 0x34, 0x12 }; - HANDLE address2 = VirtualAllocEx(hProcess, NULL, convertFunctionSize+sizeof(DWORD)+SHELL_SIZE+convertFunctionSize*3, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);//4 extra bytes for the address + HANDLE address2 = VirtualAllocEx(hProcess, NULL, byteCounter+sizeof(DWORD)+SHELL_SIZE+byteCounter*3, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);//4 extra bytes for the address if(!address2) return FALSE; - if(!WriteProcessMemory(hProcess, (void*)address2, (void*)buffer, convertFunctionSize, NULL))//Write the function to memory + if(!WriteProcessMemory(hProcess, (void*)address2, (void*)newFunction, byteCounter, NULL))//Write the function to memory return FALSE; - if(!WriteProcessMemory(hProcess, (void*)address2+convertFunctionSize+sizeof(DWORD)+SHELL_SIZE, (void*)buffer, convertFunctionSize, NULL))//Write the function to memory + if(!WriteProcessMemory(hProcess, (void*)address2+byteCounter+sizeof(DWORD)+SHELL_SIZE, (void*)newFunction, byteCounter, NULL))//Write the function to memory return FALSE; - DWORD olaAmigos = (DWORD)address2+convertFunctionSize+sizeof(DWORD); - if(!WriteProcessMemory(hProcess, (void*)address2+convertFunctionSize, &olaAmigos, sizeof(DWORD), NULL))//Write the address of the shellcode + DWORD olaAmigos = (DWORD)address2+byteCounter+sizeof(DWORD); + if(!WriteProcessMemory(hProcess, (void*)address2+byteCounter, &olaAmigos, sizeof(DWORD), NULL))//Write the address of the shellcode return FALSE; //Convert shell code to self modyfing code //setting the correct counter address - DWORD counterAddress = (DWORD)address2+convertFunctionSize+sizeof(DWORD)+0x3; + DWORD counterAddress = (DWORD)address2+byteCounter+sizeof(DWORD)+0x3; memcpy(sexyShell+0x11, &counterAddress,sizeof(DWORD)); memcpy(sexyShell+0x59, &counterAddress,sizeof(DWORD)); //setting the function size - memcpy(sexyShell+0x1A, &convertFunctionSize,sizeof(DWORD)); + memcpy(sexyShell+0x1A, &byteCounter,sizeof(DWORD)); //setting the startAddress - DWORD startAddress = (DWORD)address2+convertFunctionSize+sizeof(DWORD)+SHELL_SIZE; + DWORD startAddress = (DWORD)address2+byteCounter+sizeof(DWORD)+SHELL_SIZE; memcpy(sexyShell+0x1F, &startAddress,sizeof(DWORD)); //setting addressOfUnencripted - DWORD addressOfUnencripted = (DWORD)address2+convertFunctionSize+sizeof(DWORD)+0x24; + DWORD addressOfUnencripted = (DWORD)address2+byteCounter+sizeof(DWORD)+0x24; memcpy(sexyShell+0x24, &startAddress,sizeof(DWORD)); memcpy(sexyShell+0x3F, &addressOfUnencripted, sizeof(DWORD)); memcpy(sexyShell+0x4E, &addressOfUnencripted, sizeof(DWORD)); @@ -533,11 +125,11 @@ BOOL interptFunction(HANDLE hProcess, FUNCTION function, PASM_INSTRUCTION pAsmIn //functionStoreAddress memcpy(sexyShell+0x32, &address2,sizeof(DWORD)); - if(!WriteProcessMemory(hProcess, (void*)address2+convertFunctionSize+sizeof(DWORD), sexyShell, SHELL_SIZE, NULL))//Write the shellcode + if(!WriteProcessMemory(hProcess, (void*)address2+byteCounter+sizeof(DWORD), sexyShell, SHELL_SIZE, NULL))//Write the shellcode return FALSE; - DWORD fdxTmp = (DWORD)address2+convertFunctionSize; + DWORD fdxTmp = (DWORD)address2+byteCounter; unsigned char absJmp[6] = "\xFF\x25"; memcpy(absJmp+2, &fdxTmp, sizeof(DWORD));//Copy the address that contains the address of the function @@ -549,283 +141,134 @@ BOOL interptFunction(HANDLE hProcess, FUNCTION function, PASM_INSTRUCTION pAsmIn return TRUE; - } -BOOL analyzeFunction(const unsigned char *buffer, DWORD size,PASM_INSTRUCTION pAsmInstructionList, PASM_INSTRUCTION final){ - +BOOL fixRelativeJmpOrCall(int64_t jmpLocation, DWORD numBytes, PABS_INSTRUCTION *pAbsInstruction, DWORD originalSize,BOOLEAN isJmp){ - static DWORD counter = 0; - static PASM_INSTRUCTION tmpAsm = NULL; - + if(!(*pAbsInstruction)) + *pAbsInstruction = malloc(sizeof(ABS_INSTRUCTION)); + else + return fixRelativeJmpOrCall(jmpLocation, numBytes, &((*pAbsInstruction)->next), originalSize,isJmp); - if(!final) + if(!(*pAbsInstruction))//It failed return FALSE; - if(counter > size) - return FALSE; //we fucked - + memset((*pAbsInstruction), 0, sizeof(ABS_INSTRUCTION)); - tmpAsm = NULL; //Clean the fucker - tmpAsm = getCurrentInstruction(buffer+counter, pAsmInstructionList); - - if(!tmpAsm){ - char error[69]; - sprintf(error, "Unknown instruction wtf %02X", buffer[counter]); - MessageBoxA(NULL, error, "fuck", 0); - return FALSE; - } + (*pAbsInstruction)->opcode = 0xFF; + (*pAbsInstruction)->modReg = (((isJmp ? 2 : 4) << 3) | 5); + (*pAbsInstruction)->address = jmpLocation; + (*pAbsInstruction)->bytePosition = numBytes; + (*pAbsInstruction)->originalSize = originalSize; + (*pAbsInstruction)->alreadyStored = FALSE;//just to be sure + (*pAbsInstruction)->next = NULL; - memcpy(final, tmpAsm, sizeof(ASM_INSTRUCTION)); // we altered the original so we must have a copy of it - counter += tmpAsm->size; - final->next = NULL; + return TRUE; - if(counter == size)//the end - return TRUE; +} + +BOOL getAbsoluteAddressStorage(HANDLE hProcess, PABS_INSTRUCTION pAbsInstruction){ - //not the end... keep copying - final->next = malloc(sizeof(ASM_INSTRUCTION)); + DWORD counter = 0; + PABS_INSTRUCTION tmp = pAbsInstruction; + PABS_INSTRUCTION tmp2 = NULL; - if(!(final->next)){ - MessageBoxA(NULL, "Failed to allocate space for the next instruction", "FAIL", 0); - return FALSE; + //Get how many addresses we'll need(doesnt exclude repeated ones) + while(counter){ + tmp = tmp->next; + counter++; } - memset(final->next, 0, sizeof(ASM_INSTRUCTION)); - return analyzeFunction(buffer, size, pAsmInstructionList, final->next); -} - -PASM_INSTRUCTION getCurrentInstruction(const unsigned char *buffer, PASM_INSTRUCTION pAsmInstructionList){ - - if(!pAsmInstructionList) - return NULL; + DWORD *addressBuffer = malloc(counter * sizeof(DWORD)); + if(!addressBuffer) + return FALSE; - if(buffer[0] == pAsmInstructionList->opcode){ + //Give each abs instruction a unique id + DWORD curId = 0; + tmp = pAbsInstruction; + while(tmp){ - if(pAsmInstructionList->variableSize || pAsmInstructionList->sharedOpcode){ - - if(pAsmInstructionList->variableSize) //fix the size - pAsmInstructionList->defineSize(pAsmInstructionList, buffer); - - if(pAsmInstructionList->sharedOpcode){ //make sure it's the correct instruction - - if(((buffer[1] >> 3) & 7) == pAsmInstructionList->regValue)//key point - return pAsmInstructionList; - - return getCurrentInstruction(buffer, pAsmInstructionList->next); - } + if(curId > counter)//We fucked + return FALSE; + if(tmp->alreadyStored){ + tmp = tmp->next; + continue; //Dont increase the id because i'll get us problems } - return pAsmInstructionList; - } - - return getCurrentInstruction(buffer, pAsmInstructionList->next); - -} - -BOOL fixRelativeAddresses(PASM_INSTRUCTION pAsmInstruction, FUNCTION function,const unsigned char* buffer){ - - static PABS_INSTRUCTION tmpAbs = NULL; - static DWORD counter = 0; - - tmpAbs = NULL; - - if(!pAsmInstruction && function.size == counter) - return TRUE; - - if(pAsmInstruction->needToFix){ + //Copy to the address buffer + addressBuffer[curId] = tmp->address; + tmp->idInStorage = curId; + tmp->alreadyStored = TRUE; - if(pAsmInstruction->opcode == REL_CALL || - pAsmInstruction->opcode == REL_JMP || pAsmInstruction->opcode == REL_SHORT_JMP){ - + tmp2 = tmp->next; + while(tmp2){ - DWORD* jmpLocation = (DWORD*)(buffer+counter+1); - if((function.size - counter) >= ((pAsmInstruction->size > 2) ? *jmpLocation : buffer[counter+1])){//only jump if the jmp is to outside the function - pAsmInstruction->needToFix = FALSE;//No need to fix then - counter += pAsmInstruction->size; - return fixRelativeAddresses(pAsmInstruction->next, function,buffer); + if(tmp2->alreadyStored){ + tmp2 = tmp2->next; + continue; } - - tmpAbs = malloc(sizeof(ABS_INSTRUCTION)); - - if(!tmpAbs){ - MessageBoxA(NULL, "Couldnt allocate space for abs instruction", "nop", 0); - return FALSE; + if(tmp2->address == addressBuffer[curId]){ + tmp2->idInStorage = curId; + tmp2->alreadyStored = TRUE; } - tmpAbs->opcode = ABS_NEAR_JUMP; - - tmpAbs->modReg = 0; //Clear it - - tmpAbs->modReg |= (pAsmInstruction->opcode == REL_CALL) ? ABS_NEAR_CALL_REG : ABS_NEAR_JUMP_REG; - - DWORD* tmpDword = NULL; - tmpDword = (DWORD*)(buffer+counter+1); //Only works this way?? - - tmpAbs->address = *tmpDword + function.startAddr + counter + 5; - - pAsmInstruction->fixedInstruction = tmpAbs; - - pAsmInstruction->size2 = 6; - + tmp2 = tmp2->next; } - } - - counter += pAsmInstruction->size; - - return fixRelativeAddresses(pAsmInstruction->next, function,buffer); -} - -DWORD getConvertedFunctionSize(PASM_INSTRUCTION pAsmInstruction){ - - if(!pAsmInstruction) - return 0; - - return (pAsmInstruction->fixedInstruction ? pAsmInstruction->size2 : pAsmInstruction->size) + getConvertedFunctionSize(pAsmInstruction->next); -} - - -unsigned char *convertFunction(PASM_INSTRUCTION pAsmInstruction,const unsigned char* buffer,DWORD size, DWORD allocatedMemoryAddress){ - - static DWORD fixedCounter = 0; //Used for the new function - static DWORD bufferCounter = 0;//They move at different speeds - - static unsigned char *fixedFunction = NULL; - - if(size == fixedCounter) - return fixedFunction; - else if(size < fixedCounter) //we fucked up - return NULL; - - if(!fixedFunction){ - fixedFunction = malloc(size); - if(!fixedFunction) - return NULL; + tmp = tmp->next; + curId++; } + HANDLE addressBufferStorage = VirtualAllocEx(hProcess, NULL, (curId+1)*sizeof(DWORD), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); - //Choose which to copy - if(pAsmInstruction->fixedInstruction){ - - pAsmInstruction->fixedInstruction->address = sizeof(DWORD) * pAsmInstruction->fixedInstruction->idInStorage + allocatedMemoryAddress; // set the correct address - memcpy((void*)fixedFunction+fixedCounter, pAsmInstruction->fixedInstruction, pAsmInstruction->size2); - - fixedCounter += pAsmInstruction->size2; - } - else{ - - memcpy((void*)fixedFunction+fixedCounter, buffer+bufferCounter, pAsmInstruction->size); - fixedCounter += pAsmInstruction->size; - } - - bufferCounter += pAsmInstruction->size; //Need to move as the original - - return convertFunction(pAsmInstruction->next, buffer, size, allocatedMemoryAddress); - - -} - -BOOL addAbsoluteAddressesToStorage(PASM_INSTRUCTION pAsmInstruction, PABS_ADDRESS_STORAGE absAddrStorage){ - - - if(!pAsmInstruction)//cant be sure enoguh - return TRUE; - + if(!addressBufferStorage) + return FALSE; - if(pAsmInstruction->fixedInstruction){ - - if(!absAddrStorage)//Wow + //Now that everything is setup we'll change the id to the correct memory address + tmp = pAbsInstruction; + while(tmp){ + if(!tmp->alreadyStored)//?? return FALSE; - - absAddrStorage->instruction = pAsmInstruction->fixedInstruction; - absAddrStorage->next = NULL; - - if(!pAsmInstruction->next) //no need to reserve more space in memory if it's the end - return TRUE; - - absAddrStorage->next = malloc(sizeof(ABS_ADDRESS_STORAGE)); - - if(!absAddrStorage->next) - return FALSE; - - memset(absAddrStorage->next, 0, sizeof(ABS_ADDRESS_STORAGE)); - - return addAbsoluteAddressesToStorage(pAsmInstruction->next, absAddrStorage->next); + tmp->address = (DWORD)(addressBufferStorage+tmp->idInStorage*sizeof(DWORD)); + tmp = tmp->next; } - return addAbsoluteAddressesToStorage(pAsmInstruction->next, absAddrStorage);//nothing was added to absAddrStorage -} - -//Get how many addresses it should store it doesn't ignore the repeated -BOOL countStorageId(PABS_ADDRESS_STORAGE absAddrStorage){ - - static DWORD counter = 0; - - if(!absAddrStorage || !absAddrStorage->instruction)//the end m8 - return counter; - - counter++; - return countStorageId(absAddrStorage->next); + if(!WriteProcessMemory(hProcess, (void*)addressBufferStorage, addressBuffer, (curId+1)*sizeof(DWORD), NULL)) + return FALSE; + return TRUE; } - -BOOL fixAbsoluteAddresses(PABS_ADDRESS_STORAGE absAddrStorage, DWORD* counter){ +BYTE* createNewFunction(const BYTE *originalFunction, DWORD newFunctionSize, PABS_INSTRUCTION pAbsInstruction){ - DWORD storageIdCount = countStorageId(absAddrStorage); + DWORD curPosOrig = 0, curPosNew = 0; - if(!storageIdCount)//No need to fix anything - return TRUE; - - DWORD *addressBuffer = malloc(sizeof(DWORD) * storageIdCount); + PABS_INSTRUCTION tmpAbs; + tmpAbs = pAbsInstruction; - if(!addressBuffer)//fail - return FALSE; - - - PABS_ADDRESS_STORAGE tmpStorage = NULL, tmpStorage2 = NULL; + BYTE* newFunction = NULL; + newFunction = malloc(newFunctionSize); - //Tired of recursion - tmpStorage = absAddrStorage; - - while(tmpStorage){ - - - if(tmpStorage->alreadyInStorage){ //No need to add again - tmpStorage = tmpStorage->next; - continue; - } - - if(tmpStorage->instruction){ - + if(!newFunction)//Failed + return newFunction; - addressBuffer[*counter] = tmpStorage->instruction->address;//put it in the buffer - tmpStorage->instruction->idInStorage = *counter; - tmpStorage->alreadyInStorage = TRUE; - - tmpStorage2 = tmpStorage->next; + memset(newFunction, 0, newFunctionSize); + + while(curPosNew != newFunctionSize){ - while(tmpStorage2){ //same logic - - if(tmpStorage2->instruction){ - if(!tmpStorage2->alreadyInStorage && addressBuffer[*counter] == tmpStorage2->instruction->address){ - tmpStorage2->alreadyInStorage = TRUE; - tmpStorage2->instruction->idInStorage = *counter; - } - } + memcpy((void*)newFunction+curPosNew, (void*)originalFunction+curPosOrig, ((tmpAbs == NULL) ? newFunctionSize - 1: tmpAbs->bytePosition) - curPosOrig); + curPosNew += (((tmpAbs == NULL) ? newFunctionSize - 1: tmpAbs->bytePosition) - curPosOrig) ; + curPosOrig += (((tmpAbs == NULL) ? newFunctionSize - 1: tmpAbs->bytePosition) - curPosOrig); - tmpStorage2 = tmpStorage2->next; - - } + if(tmpAbs){ + memcpy((void*)newFunction+curPosNew, tmpAbs, 6);//Copy the fixed + curPosNew += 6; + curPosOrig += tmpAbs->originalSize; + tmpAbs = tmpAbs->next; } - - - tmpStorage = tmpStorage->next; - (*counter)++; } - return (BOOL)addressBuffer; + return newFunction; } \ No newline at end of file diff --git a/include/arm.h b/include/arm.h new file mode 100644 index 0000000..c6ab15f --- /dev/null +++ b/include/arm.h @@ -0,0 +1,883 @@ +#ifndef CAPSTONE_ARM_H +#define CAPSTONE_ARM_H + +/* Capstone Disassembly Engine */ +/* By Nguyen Anh Quynh , 2013-2014 */ + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(_MSC_VER) || !defined(_KERNEL_MODE) +#include +#endif + +#include "platform.h" + +#ifdef _MSC_VER +#pragma warning(disable:4201) +#endif + +//> ARM shift type +typedef enum arm_shifter { + ARM_SFT_INVALID = 0, + ARM_SFT_ASR, // shift with immediate const + ARM_SFT_LSL, // shift with immediate const + ARM_SFT_LSR, // shift with immediate const + ARM_SFT_ROR, // shift with immediate const + ARM_SFT_RRX, // shift with immediate const + ARM_SFT_ASR_REG, // shift with register + ARM_SFT_LSL_REG, // shift with register + ARM_SFT_LSR_REG, // shift with register + ARM_SFT_ROR_REG, // shift with register + ARM_SFT_RRX_REG, // shift with register +} arm_shifter; + +//> ARM condition code +typedef enum arm_cc { + ARM_CC_INVALID = 0, + ARM_CC_EQ, // Equal Equal + ARM_CC_NE, // Not equal Not equal, or unordered + ARM_CC_HS, // Carry set >, ==, or unordered + ARM_CC_LO, // Carry clear Less than + ARM_CC_MI, // Minus, negative Less than + ARM_CC_PL, // Plus, positive or zero >, ==, or unordered + ARM_CC_VS, // Overflow Unordered + ARM_CC_VC, // No overflow Not unordered + ARM_CC_HI, // Unsigned higher Greater than, or unordered + ARM_CC_LS, // Unsigned lower or same Less than or equal + ARM_CC_GE, // Greater than or equal Greater than or equal + ARM_CC_LT, // Less than Less than, or unordered + ARM_CC_GT, // Greater than Greater than + ARM_CC_LE, // Less than or equal <, ==, or unordered + ARM_CC_AL // Always (unconditional) Always (unconditional) +} arm_cc; + +typedef enum arm_sysreg { + //> Special registers for MSR + ARM_SYSREG_INVALID = 0, + + // SPSR* registers can be OR combined + ARM_SYSREG_SPSR_C = 1, + ARM_SYSREG_SPSR_X = 2, + ARM_SYSREG_SPSR_S = 4, + ARM_SYSREG_SPSR_F = 8, + + // CPSR* registers can be OR combined + ARM_SYSREG_CPSR_C = 16, + ARM_SYSREG_CPSR_X = 32, + ARM_SYSREG_CPSR_S = 64, + ARM_SYSREG_CPSR_F = 128, + + // independent registers + ARM_SYSREG_APSR = 256, + ARM_SYSREG_APSR_G, + ARM_SYSREG_APSR_NZCVQ, + ARM_SYSREG_APSR_NZCVQG, + + ARM_SYSREG_IAPSR, + ARM_SYSREG_IAPSR_G, + ARM_SYSREG_IAPSR_NZCVQG, + + ARM_SYSREG_EAPSR, + ARM_SYSREG_EAPSR_G, + ARM_SYSREG_EAPSR_NZCVQG, + + ARM_SYSREG_XPSR, + ARM_SYSREG_XPSR_G, + ARM_SYSREG_XPSR_NZCVQG, + + ARM_SYSREG_IPSR, + ARM_SYSREG_EPSR, + ARM_SYSREG_IEPSR, + + ARM_SYSREG_MSP, + ARM_SYSREG_PSP, + ARM_SYSREG_PRIMASK, + ARM_SYSREG_BASEPRI, + ARM_SYSREG_BASEPRI_MAX, + ARM_SYSREG_FAULTMASK, + ARM_SYSREG_CONTROL, +} arm_sysreg; + +//> The memory barrier constants map directly to the 4-bit encoding of +//> the option field for Memory Barrier operations. +typedef enum arm_mem_barrier { + ARM_MB_INVALID = 0, + ARM_MB_RESERVED_0, + ARM_MB_OSHLD, + ARM_MB_OSHST, + ARM_MB_OSH, + ARM_MB_RESERVED_4, + ARM_MB_NSHLD, + ARM_MB_NSHST, + ARM_MB_NSH, + ARM_MB_RESERVED_8, + ARM_MB_ISHLD, + ARM_MB_ISHST, + ARM_MB_ISH, + ARM_MB_RESERVED_12, + ARM_MB_LD, + ARM_MB_ST, + ARM_MB_SY, +} arm_mem_barrier; + +//> Operand type for instruction's operands +typedef enum arm_op_type { + ARM_OP_INVALID = 0, // = CS_OP_INVALID (Uninitialized). + ARM_OP_REG, // = CS_OP_REG (Register operand). + ARM_OP_IMM, // = CS_OP_IMM (Immediate operand). + ARM_OP_MEM, // = CS_OP_MEM (Memory operand). + ARM_OP_FP, // = CS_OP_FP (Floating-Point operand). + ARM_OP_CIMM = 64, // C-Immediate (coprocessor registers) + ARM_OP_PIMM, // P-Immediate (coprocessor registers) + ARM_OP_SETEND, // operand for SETEND instruction + ARM_OP_SYSREG, // MSR/MSR special register operand +} arm_op_type; + +//> Operand type for SETEND instruction +typedef enum arm_setend_type { + ARM_SETEND_INVALID = 0, // Uninitialized. + ARM_SETEND_BE, // BE operand. + ARM_SETEND_LE, // LE operand +} arm_setend_type; + +typedef enum arm_cpsmode_type { + ARM_CPSMODE_INVALID = 0, + ARM_CPSMODE_IE = 2, + ARM_CPSMODE_ID = 3 +} arm_cpsmode_type; + +//> Operand type for SETEND instruction +typedef enum arm_cpsflag_type { + ARM_CPSFLAG_INVALID = 0, + ARM_CPSFLAG_F = 1, + ARM_CPSFLAG_I = 2, + ARM_CPSFLAG_A = 4, + ARM_CPSFLAG_NONE = 16, // no flag +} arm_cpsflag_type; + +//> Data type for elements of vector instructions. +typedef enum arm_vectordata_type { + ARM_VECTORDATA_INVALID = 0, + + // Integer type + ARM_VECTORDATA_I8, + ARM_VECTORDATA_I16, + ARM_VECTORDATA_I32, + ARM_VECTORDATA_I64, + + // Signed integer type + ARM_VECTORDATA_S8, + ARM_VECTORDATA_S16, + ARM_VECTORDATA_S32, + ARM_VECTORDATA_S64, + + // Unsigned integer type + ARM_VECTORDATA_U8, + ARM_VECTORDATA_U16, + ARM_VECTORDATA_U32, + ARM_VECTORDATA_U64, + + // Data type for VMUL/VMULL + ARM_VECTORDATA_P8, + + // Floating type + ARM_VECTORDATA_F32, + ARM_VECTORDATA_F64, + + // Convert float <-> float + ARM_VECTORDATA_F16F64, // f16.f64 + ARM_VECTORDATA_F64F16, // f64.f16 + ARM_VECTORDATA_F32F16, // f32.f16 + ARM_VECTORDATA_F16F32, // f32.f16 + ARM_VECTORDATA_F64F32, // f64.f32 + ARM_VECTORDATA_F32F64, // f32.f64 + + // Convert integer <-> float + ARM_VECTORDATA_S32F32, // s32.f32 + ARM_VECTORDATA_U32F32, // u32.f32 + ARM_VECTORDATA_F32S32, // f32.s32 + ARM_VECTORDATA_F32U32, // f32.u32 + ARM_VECTORDATA_F64S16, // f64.s16 + ARM_VECTORDATA_F32S16, // f32.s16 + ARM_VECTORDATA_F64S32, // f64.s32 + ARM_VECTORDATA_S16F64, // s16.f64 + ARM_VECTORDATA_S16F32, // s16.f64 + ARM_VECTORDATA_S32F64, // s32.f64 + ARM_VECTORDATA_U16F64, // u16.f64 + ARM_VECTORDATA_U16F32, // u16.f32 + ARM_VECTORDATA_U32F64, // u32.f64 + ARM_VECTORDATA_F64U16, // f64.u16 + ARM_VECTORDATA_F32U16, // f32.u16 + ARM_VECTORDATA_F64U32, // f64.u32 +} arm_vectordata_type; + +// Instruction's operand referring to memory +// This is associated with ARM_OP_MEM operand type above +typedef struct arm_op_mem { + unsigned int base; // base register + unsigned int index; // index register + int scale; // scale for index register (can be 1, or -1) + int disp; // displacement/offset value +} arm_op_mem; + +// Instruction operand +typedef struct cs_arm_op { + int vector_index; // Vector Index for some vector operands (or -1 if irrelevant) + struct { + arm_shifter type; + unsigned int value; + } shift; + arm_op_type type; // operand type + union { + unsigned int reg; // register value for REG/SYSREG operand + int32_t imm; // immediate value for C-IMM, P-IMM or IMM operand + double fp; // floating point value for FP operand + arm_op_mem mem; // base/index/scale/disp value for MEM operand + arm_setend_type setend; // SETEND instruction's operand type + }; + // in some instructions, an operand can be subtracted or added to + // the base register, + bool subtracted; // if TRUE, this operand is subtracted. otherwise, it is added. +} cs_arm_op; + +// Instruction structure +typedef struct cs_arm { + bool usermode; // User-mode registers to be loaded (for LDM/STM instructions) + int vector_size; // Scalar size for vector instructions + arm_vectordata_type vector_data; // Data type for elements of vector instructions + arm_cpsmode_type cps_mode; // CPS mode for CPS instruction + arm_cpsflag_type cps_flag; // CPS mode for CPS instruction + arm_cc cc; // conditional code for this insn + bool update_flags; // does this insn update flags? + bool writeback; // does this insn write-back? + arm_mem_barrier mem_barrier; // Option for some memory barrier instructions + + // Number of operands of this instruction, + // or 0 when instruction has no operand. + uint8_t op_count; + + cs_arm_op operands[36]; // operands for this instruction. +} cs_arm; + +//> ARM registers +typedef enum arm_reg { + ARM_REG_INVALID = 0, + ARM_REG_APSR, + ARM_REG_APSR_NZCV, + ARM_REG_CPSR, + ARM_REG_FPEXC, + ARM_REG_FPINST, + ARM_REG_FPSCR, + ARM_REG_FPSCR_NZCV, + ARM_REG_FPSID, + ARM_REG_ITSTATE, + ARM_REG_LR, + ARM_REG_PC, + ARM_REG_SP, + ARM_REG_SPSR, + ARM_REG_D0, + ARM_REG_D1, + ARM_REG_D2, + ARM_REG_D3, + ARM_REG_D4, + ARM_REG_D5, + ARM_REG_D6, + ARM_REG_D7, + ARM_REG_D8, + ARM_REG_D9, + ARM_REG_D10, + ARM_REG_D11, + ARM_REG_D12, + ARM_REG_D13, + ARM_REG_D14, + ARM_REG_D15, + ARM_REG_D16, + ARM_REG_D17, + ARM_REG_D18, + ARM_REG_D19, + ARM_REG_D20, + ARM_REG_D21, + ARM_REG_D22, + ARM_REG_D23, + ARM_REG_D24, + ARM_REG_D25, + ARM_REG_D26, + ARM_REG_D27, + ARM_REG_D28, + ARM_REG_D29, + ARM_REG_D30, + ARM_REG_D31, + ARM_REG_FPINST2, + ARM_REG_MVFR0, + ARM_REG_MVFR1, + ARM_REG_MVFR2, + ARM_REG_Q0, + ARM_REG_Q1, + ARM_REG_Q2, + ARM_REG_Q3, + ARM_REG_Q4, + ARM_REG_Q5, + ARM_REG_Q6, + ARM_REG_Q7, + ARM_REG_Q8, + ARM_REG_Q9, + ARM_REG_Q10, + ARM_REG_Q11, + ARM_REG_Q12, + ARM_REG_Q13, + ARM_REG_Q14, + ARM_REG_Q15, + ARM_REG_R0, + ARM_REG_R1, + ARM_REG_R2, + ARM_REG_R3, + ARM_REG_R4, + ARM_REG_R5, + ARM_REG_R6, + ARM_REG_R7, + ARM_REG_R8, + ARM_REG_R9, + ARM_REG_R10, + ARM_REG_R11, + ARM_REG_R12, + ARM_REG_S0, + ARM_REG_S1, + ARM_REG_S2, + ARM_REG_S3, + ARM_REG_S4, + ARM_REG_S5, + ARM_REG_S6, + ARM_REG_S7, + ARM_REG_S8, + ARM_REG_S9, + ARM_REG_S10, + ARM_REG_S11, + ARM_REG_S12, + ARM_REG_S13, + ARM_REG_S14, + ARM_REG_S15, + ARM_REG_S16, + ARM_REG_S17, + ARM_REG_S18, + ARM_REG_S19, + ARM_REG_S20, + ARM_REG_S21, + ARM_REG_S22, + ARM_REG_S23, + ARM_REG_S24, + ARM_REG_S25, + ARM_REG_S26, + ARM_REG_S27, + ARM_REG_S28, + ARM_REG_S29, + ARM_REG_S30, + ARM_REG_S31, + + ARM_REG_ENDING, // <-- mark the end of the list or registers + + //> alias registers + ARM_REG_R13 = ARM_REG_SP, + ARM_REG_R14 = ARM_REG_LR, + ARM_REG_R15 = ARM_REG_PC, + + ARM_REG_SB = ARM_REG_R9, + ARM_REG_SL = ARM_REG_R10, + ARM_REG_FP = ARM_REG_R11, + ARM_REG_IP = ARM_REG_R12, +} arm_reg; + +//> ARM instruction +typedef enum arm_insn { + ARM_INS_INVALID = 0, + + ARM_INS_ADC, + ARM_INS_ADD, + ARM_INS_ADR, + ARM_INS_AESD, + ARM_INS_AESE, + ARM_INS_AESIMC, + ARM_INS_AESMC, + ARM_INS_AND, + ARM_INS_BFC, + ARM_INS_BFI, + ARM_INS_BIC, + ARM_INS_BKPT, + ARM_INS_BL, + ARM_INS_BLX, + ARM_INS_BX, + ARM_INS_BXJ, + ARM_INS_B, + ARM_INS_CDP, + ARM_INS_CDP2, + ARM_INS_CLREX, + ARM_INS_CLZ, + ARM_INS_CMN, + ARM_INS_CMP, + ARM_INS_CPS, + ARM_INS_CRC32B, + ARM_INS_CRC32CB, + ARM_INS_CRC32CH, + ARM_INS_CRC32CW, + ARM_INS_CRC32H, + ARM_INS_CRC32W, + ARM_INS_DBG, + ARM_INS_DMB, + ARM_INS_DSB, + ARM_INS_EOR, + ARM_INS_VMOV, + ARM_INS_FLDMDBX, + ARM_INS_FLDMIAX, + ARM_INS_VMRS, + ARM_INS_FSTMDBX, + ARM_INS_FSTMIAX, + ARM_INS_HINT, + ARM_INS_HLT, + ARM_INS_ISB, + ARM_INS_LDA, + ARM_INS_LDAB, + ARM_INS_LDAEX, + ARM_INS_LDAEXB, + ARM_INS_LDAEXD, + ARM_INS_LDAEXH, + ARM_INS_LDAH, + ARM_INS_LDC2L, + ARM_INS_LDC2, + ARM_INS_LDCL, + ARM_INS_LDC, + ARM_INS_LDMDA, + ARM_INS_LDMDB, + ARM_INS_LDM, + ARM_INS_LDMIB, + ARM_INS_LDRBT, + ARM_INS_LDRB, + ARM_INS_LDRD, + ARM_INS_LDREX, + ARM_INS_LDREXB, + ARM_INS_LDREXD, + ARM_INS_LDREXH, + ARM_INS_LDRH, + ARM_INS_LDRHT, + ARM_INS_LDRSB, + ARM_INS_LDRSBT, + ARM_INS_LDRSH, + ARM_INS_LDRSHT, + ARM_INS_LDRT, + ARM_INS_LDR, + ARM_INS_MCR, + ARM_INS_MCR2, + ARM_INS_MCRR, + ARM_INS_MCRR2, + ARM_INS_MLA, + ARM_INS_MLS, + ARM_INS_MOV, + ARM_INS_MOVT, + ARM_INS_MOVW, + ARM_INS_MRC, + ARM_INS_MRC2, + ARM_INS_MRRC, + ARM_INS_MRRC2, + ARM_INS_MRS, + ARM_INS_MSR, + ARM_INS_MUL, + ARM_INS_MVN, + ARM_INS_ORR, + ARM_INS_PKHBT, + ARM_INS_PKHTB, + ARM_INS_PLDW, + ARM_INS_PLD, + ARM_INS_PLI, + ARM_INS_QADD, + ARM_INS_QADD16, + ARM_INS_QADD8, + ARM_INS_QASX, + ARM_INS_QDADD, + ARM_INS_QDSUB, + ARM_INS_QSAX, + ARM_INS_QSUB, + ARM_INS_QSUB16, + ARM_INS_QSUB8, + ARM_INS_RBIT, + ARM_INS_REV, + ARM_INS_REV16, + ARM_INS_REVSH, + ARM_INS_RFEDA, + ARM_INS_RFEDB, + ARM_INS_RFEIA, + ARM_INS_RFEIB, + ARM_INS_RSB, + ARM_INS_RSC, + ARM_INS_SADD16, + ARM_INS_SADD8, + ARM_INS_SASX, + ARM_INS_SBC, + ARM_INS_SBFX, + ARM_INS_SDIV, + ARM_INS_SEL, + ARM_INS_SETEND, + ARM_INS_SHA1C, + ARM_INS_SHA1H, + ARM_INS_SHA1M, + ARM_INS_SHA1P, + ARM_INS_SHA1SU0, + ARM_INS_SHA1SU1, + ARM_INS_SHA256H, + ARM_INS_SHA256H2, + ARM_INS_SHA256SU0, + ARM_INS_SHA256SU1, + ARM_INS_SHADD16, + ARM_INS_SHADD8, + ARM_INS_SHASX, + ARM_INS_SHSAX, + ARM_INS_SHSUB16, + ARM_INS_SHSUB8, + ARM_INS_SMC, + ARM_INS_SMLABB, + ARM_INS_SMLABT, + ARM_INS_SMLAD, + ARM_INS_SMLADX, + ARM_INS_SMLAL, + ARM_INS_SMLALBB, + ARM_INS_SMLALBT, + ARM_INS_SMLALD, + ARM_INS_SMLALDX, + ARM_INS_SMLALTB, + ARM_INS_SMLALTT, + ARM_INS_SMLATB, + ARM_INS_SMLATT, + ARM_INS_SMLAWB, + ARM_INS_SMLAWT, + ARM_INS_SMLSD, + ARM_INS_SMLSDX, + ARM_INS_SMLSLD, + ARM_INS_SMLSLDX, + ARM_INS_SMMLA, + ARM_INS_SMMLAR, + ARM_INS_SMMLS, + ARM_INS_SMMLSR, + ARM_INS_SMMUL, + ARM_INS_SMMULR, + ARM_INS_SMUAD, + ARM_INS_SMUADX, + ARM_INS_SMULBB, + ARM_INS_SMULBT, + ARM_INS_SMULL, + ARM_INS_SMULTB, + ARM_INS_SMULTT, + ARM_INS_SMULWB, + ARM_INS_SMULWT, + ARM_INS_SMUSD, + ARM_INS_SMUSDX, + ARM_INS_SRSDA, + ARM_INS_SRSDB, + ARM_INS_SRSIA, + ARM_INS_SRSIB, + ARM_INS_SSAT, + ARM_INS_SSAT16, + ARM_INS_SSAX, + ARM_INS_SSUB16, + ARM_INS_SSUB8, + ARM_INS_STC2L, + ARM_INS_STC2, + ARM_INS_STCL, + ARM_INS_STC, + ARM_INS_STL, + ARM_INS_STLB, + ARM_INS_STLEX, + ARM_INS_STLEXB, + ARM_INS_STLEXD, + ARM_INS_STLEXH, + ARM_INS_STLH, + ARM_INS_STMDA, + ARM_INS_STMDB, + ARM_INS_STM, + ARM_INS_STMIB, + ARM_INS_STRBT, + ARM_INS_STRB, + ARM_INS_STRD, + ARM_INS_STREX, + ARM_INS_STREXB, + ARM_INS_STREXD, + ARM_INS_STREXH, + ARM_INS_STRH, + ARM_INS_STRHT, + ARM_INS_STRT, + ARM_INS_STR, + ARM_INS_SUB, + ARM_INS_SVC, + ARM_INS_SWP, + ARM_INS_SWPB, + ARM_INS_SXTAB, + ARM_INS_SXTAB16, + ARM_INS_SXTAH, + ARM_INS_SXTB, + ARM_INS_SXTB16, + ARM_INS_SXTH, + ARM_INS_TEQ, + ARM_INS_TRAP, + ARM_INS_TST, + ARM_INS_UADD16, + ARM_INS_UADD8, + ARM_INS_UASX, + ARM_INS_UBFX, + ARM_INS_UDF, + ARM_INS_UDIV, + ARM_INS_UHADD16, + ARM_INS_UHADD8, + ARM_INS_UHASX, + ARM_INS_UHSAX, + ARM_INS_UHSUB16, + ARM_INS_UHSUB8, + ARM_INS_UMAAL, + ARM_INS_UMLAL, + ARM_INS_UMULL, + ARM_INS_UQADD16, + ARM_INS_UQADD8, + ARM_INS_UQASX, + ARM_INS_UQSAX, + ARM_INS_UQSUB16, + ARM_INS_UQSUB8, + ARM_INS_USAD8, + ARM_INS_USADA8, + ARM_INS_USAT, + ARM_INS_USAT16, + ARM_INS_USAX, + ARM_INS_USUB16, + ARM_INS_USUB8, + ARM_INS_UXTAB, + ARM_INS_UXTAB16, + ARM_INS_UXTAH, + ARM_INS_UXTB, + ARM_INS_UXTB16, + ARM_INS_UXTH, + ARM_INS_VABAL, + ARM_INS_VABA, + ARM_INS_VABDL, + ARM_INS_VABD, + ARM_INS_VABS, + ARM_INS_VACGE, + ARM_INS_VACGT, + ARM_INS_VADD, + ARM_INS_VADDHN, + ARM_INS_VADDL, + ARM_INS_VADDW, + ARM_INS_VAND, + ARM_INS_VBIC, + ARM_INS_VBIF, + ARM_INS_VBIT, + ARM_INS_VBSL, + ARM_INS_VCEQ, + ARM_INS_VCGE, + ARM_INS_VCGT, + ARM_INS_VCLE, + ARM_INS_VCLS, + ARM_INS_VCLT, + ARM_INS_VCLZ, + ARM_INS_VCMP, + ARM_INS_VCMPE, + ARM_INS_VCNT, + ARM_INS_VCVTA, + ARM_INS_VCVTB, + ARM_INS_VCVT, + ARM_INS_VCVTM, + ARM_INS_VCVTN, + ARM_INS_VCVTP, + ARM_INS_VCVTT, + ARM_INS_VDIV, + ARM_INS_VDUP, + ARM_INS_VEOR, + ARM_INS_VEXT, + ARM_INS_VFMA, + ARM_INS_VFMS, + ARM_INS_VFNMA, + ARM_INS_VFNMS, + ARM_INS_VHADD, + ARM_INS_VHSUB, + ARM_INS_VLD1, + ARM_INS_VLD2, + ARM_INS_VLD3, + ARM_INS_VLD4, + ARM_INS_VLDMDB, + ARM_INS_VLDMIA, + ARM_INS_VLDR, + ARM_INS_VMAXNM, + ARM_INS_VMAX, + ARM_INS_VMINNM, + ARM_INS_VMIN, + ARM_INS_VMLA, + ARM_INS_VMLAL, + ARM_INS_VMLS, + ARM_INS_VMLSL, + ARM_INS_VMOVL, + ARM_INS_VMOVN, + ARM_INS_VMSR, + ARM_INS_VMUL, + ARM_INS_VMULL, + ARM_INS_VMVN, + ARM_INS_VNEG, + ARM_INS_VNMLA, + ARM_INS_VNMLS, + ARM_INS_VNMUL, + ARM_INS_VORN, + ARM_INS_VORR, + ARM_INS_VPADAL, + ARM_INS_VPADDL, + ARM_INS_VPADD, + ARM_INS_VPMAX, + ARM_INS_VPMIN, + ARM_INS_VQABS, + ARM_INS_VQADD, + ARM_INS_VQDMLAL, + ARM_INS_VQDMLSL, + ARM_INS_VQDMULH, + ARM_INS_VQDMULL, + ARM_INS_VQMOVUN, + ARM_INS_VQMOVN, + ARM_INS_VQNEG, + ARM_INS_VQRDMULH, + ARM_INS_VQRSHL, + ARM_INS_VQRSHRN, + ARM_INS_VQRSHRUN, + ARM_INS_VQSHL, + ARM_INS_VQSHLU, + ARM_INS_VQSHRN, + ARM_INS_VQSHRUN, + ARM_INS_VQSUB, + ARM_INS_VRADDHN, + ARM_INS_VRECPE, + ARM_INS_VRECPS, + ARM_INS_VREV16, + ARM_INS_VREV32, + ARM_INS_VREV64, + ARM_INS_VRHADD, + ARM_INS_VRINTA, + ARM_INS_VRINTM, + ARM_INS_VRINTN, + ARM_INS_VRINTP, + ARM_INS_VRINTR, + ARM_INS_VRINTX, + ARM_INS_VRINTZ, + ARM_INS_VRSHL, + ARM_INS_VRSHRN, + ARM_INS_VRSHR, + ARM_INS_VRSQRTE, + ARM_INS_VRSQRTS, + ARM_INS_VRSRA, + ARM_INS_VRSUBHN, + ARM_INS_VSELEQ, + ARM_INS_VSELGE, + ARM_INS_VSELGT, + ARM_INS_VSELVS, + ARM_INS_VSHLL, + ARM_INS_VSHL, + ARM_INS_VSHRN, + ARM_INS_VSHR, + ARM_INS_VSLI, + ARM_INS_VSQRT, + ARM_INS_VSRA, + ARM_INS_VSRI, + ARM_INS_VST1, + ARM_INS_VST2, + ARM_INS_VST3, + ARM_INS_VST4, + ARM_INS_VSTMDB, + ARM_INS_VSTMIA, + ARM_INS_VSTR, + ARM_INS_VSUB, + ARM_INS_VSUBHN, + ARM_INS_VSUBL, + ARM_INS_VSUBW, + ARM_INS_VSWP, + ARM_INS_VTBL, + ARM_INS_VTBX, + ARM_INS_VCVTR, + ARM_INS_VTRN, + ARM_INS_VTST, + ARM_INS_VUZP, + ARM_INS_VZIP, + ARM_INS_ADDW, + ARM_INS_ASR, + ARM_INS_DCPS1, + ARM_INS_DCPS2, + ARM_INS_DCPS3, + ARM_INS_IT, + ARM_INS_LSL, + ARM_INS_LSR, + ARM_INS_ASRS, + ARM_INS_LSRS, + ARM_INS_ORN, + ARM_INS_ROR, + ARM_INS_RRX, + ARM_INS_SUBS, + ARM_INS_SUBW, + ARM_INS_TBB, + ARM_INS_TBH, + ARM_INS_CBNZ, + ARM_INS_CBZ, + ARM_INS_MOVS, + ARM_INS_POP, + ARM_INS_PUSH, + + // special instructions + ARM_INS_NOP, + ARM_INS_YIELD, + ARM_INS_WFE, + ARM_INS_WFI, + ARM_INS_SEV, + ARM_INS_SEVL, + ARM_INS_VPUSH, + ARM_INS_VPOP, + + ARM_INS_ENDING, // <-- mark the end of the list of instructions +} arm_insn; + +//> Group of ARM instructions +typedef enum arm_insn_group { + ARM_GRP_INVALID = 0, // = CS_GRP_INVALID + + //> Generic groups + // all jump instructions (conditional+direct+indirect jumps) + ARM_GRP_JUMP, // = CS_GRP_JUMP + + //> Architecture-specific groups + ARM_GRP_CRYPTO = 128, + ARM_GRP_DATABARRIER, + ARM_GRP_DIVIDE, + ARM_GRP_FPARMV8, + ARM_GRP_MULTPRO, + ARM_GRP_NEON, + ARM_GRP_T2EXTRACTPACK, + ARM_GRP_THUMB2DSP, + ARM_GRP_TRUSTZONE, + ARM_GRP_V4T, + ARM_GRP_V5T, + ARM_GRP_V5TE, + ARM_GRP_V6, + ARM_GRP_V6T2, + ARM_GRP_V7, + ARM_GRP_V8, + ARM_GRP_VFP2, + ARM_GRP_VFP3, + ARM_GRP_VFP4, + ARM_GRP_ARM, + ARM_GRP_MCLASS, + ARM_GRP_NOTMCLASS, + ARM_GRP_THUMB, + ARM_GRP_THUMB1ONLY, + ARM_GRP_THUMB2, + ARM_GRP_PREV8, + ARM_GRP_FPVMLX, + ARM_GRP_MULOPS, + ARM_GRP_CRC, + ARM_GRP_DPVFP, + ARM_GRP_V6M, + + ARM_GRP_ENDING, +} arm_insn_group; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/arm64.h b/include/arm64.h new file mode 100644 index 0000000..5091010 --- /dev/null +++ b/include/arm64.h @@ -0,0 +1,1154 @@ +#ifndef CAPSTONE_ARM64_H +#define CAPSTONE_ARM64_H + +/* Capstone Disassembly Engine */ +/* By Nguyen Anh Quynh , 2013-2014 */ + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(_MSC_VER) || !defined(_KERNEL_MODE) +#include +#endif + +#include "platform.h" + +#ifdef _MSC_VER +#pragma warning(disable:4201) +#endif + +//> ARM64 shift type +typedef enum arm64_shifter { + ARM64_SFT_INVALID = 0, + ARM64_SFT_LSL = 1, + ARM64_SFT_MSL = 2, + ARM64_SFT_LSR = 3, + ARM64_SFT_ASR = 4, + ARM64_SFT_ROR = 5, +} arm64_shifter; + +//> ARM64 extender type +typedef enum arm64_extender { + ARM64_EXT_INVALID = 0, + ARM64_EXT_UXTB = 1, + ARM64_EXT_UXTH = 2, + ARM64_EXT_UXTW = 3, + ARM64_EXT_UXTX = 4, + ARM64_EXT_SXTB = 5, + ARM64_EXT_SXTH = 6, + ARM64_EXT_SXTW = 7, + ARM64_EXT_SXTX = 8, +} arm64_extender; + +//> ARM64 condition code +typedef enum arm64_cc { + ARM64_CC_INVALID = 0, + ARM64_CC_EQ = 1, // Equal + ARM64_CC_NE = 2, // Not equal: Not equal, or unordered + ARM64_CC_HS = 3, // Unsigned higher or same: >, ==, or unordered + ARM64_CC_LO = 4, // Unsigned lower or same: Less than + ARM64_CC_MI = 5, // Minus, negative: Less than + ARM64_CC_PL = 6, // Plus, positive or zero: >, ==, or unordered + ARM64_CC_VS = 7, // Overflow: Unordered + ARM64_CC_VC = 8, // No overflow: Ordered + ARM64_CC_HI = 9, // Unsigned higher: Greater than, or unordered + ARM64_CC_LS = 10, // Unsigned lower or same: Less than or equal + ARM64_CC_GE = 11, // Greater than or equal: Greater than or equal + ARM64_CC_LT = 12, // Less than: Less than, or unordered + ARM64_CC_GT = 13, // Signed greater than: Greater than + ARM64_CC_LE = 14, // Signed less than or equal: <, ==, or unordered + ARM64_CC_AL = 15, // Always (unconditional): Always (unconditional) + ARM64_CC_NV = 16, // Always (unconditional): Always (unconditional) + // Note the NV exists purely to disassemble 0b1111. Execution + // is "always". +} arm64_cc; + +//> System registers +typedef enum arm64_mrs_reg { + //> System registers for MRS + ARM64_SYSREG_INVALID = 0, + ARM64_SYSREG_MDCCSR_EL0 = 0x9808, // 10 011 0000 0001 000 + ARM64_SYSREG_DBGDTRRX_EL0 = 0x9828, // 10 011 0000 0101 000 + ARM64_SYSREG_MDRAR_EL1 = 0x8080, // 10 000 0001 0000 000 + ARM64_SYSREG_OSLSR_EL1 = 0x808c, // 10 000 0001 0001 100 + ARM64_SYSREG_DBGAUTHSTATUS_EL1 = 0x83f6, // 10 000 0111 1110 110 + ARM64_SYSREG_PMCEID0_EL0 = 0xdce6, // 11 011 1001 1100 110 + ARM64_SYSREG_PMCEID1_EL0 = 0xdce7, // 11 011 1001 1100 111 + ARM64_SYSREG_MIDR_EL1 = 0xc000, // 11 000 0000 0000 000 + ARM64_SYSREG_CCSIDR_EL1 = 0xc800, // 11 001 0000 0000 000 + ARM64_SYSREG_CLIDR_EL1 = 0xc801, // 11 001 0000 0000 001 + ARM64_SYSREG_CTR_EL0 = 0xd801, // 11 011 0000 0000 001 + ARM64_SYSREG_MPIDR_EL1 = 0xc005, // 11 000 0000 0000 101 + ARM64_SYSREG_REVIDR_EL1 = 0xc006, // 11 000 0000 0000 110 + ARM64_SYSREG_AIDR_EL1 = 0xc807, // 11 001 0000 0000 111 + ARM64_SYSREG_DCZID_EL0 = 0xd807, // 11 011 0000 0000 111 + ARM64_SYSREG_ID_PFR0_EL1 = 0xc008, // 11 000 0000 0001 000 + ARM64_SYSREG_ID_PFR1_EL1 = 0xc009, // 11 000 0000 0001 001 + ARM64_SYSREG_ID_DFR0_EL1 = 0xc00a, // 11 000 0000 0001 010 + ARM64_SYSREG_ID_AFR0_EL1 = 0xc00b, // 11 000 0000 0001 011 + ARM64_SYSREG_ID_MMFR0_EL1 = 0xc00c, // 11 000 0000 0001 100 + ARM64_SYSREG_ID_MMFR1_EL1 = 0xc00d, // 11 000 0000 0001 101 + ARM64_SYSREG_ID_MMFR2_EL1 = 0xc00e, // 11 000 0000 0001 110 + ARM64_SYSREG_ID_MMFR3_EL1 = 0xc00f, // 11 000 0000 0001 111 + ARM64_SYSREG_ID_ISAR0_EL1 = 0xc010, // 11 000 0000 0010 000 + ARM64_SYSREG_ID_ISAR1_EL1 = 0xc011, // 11 000 0000 0010 001 + ARM64_SYSREG_ID_ISAR2_EL1 = 0xc012, // 11 000 0000 0010 010 + ARM64_SYSREG_ID_ISAR3_EL1 = 0xc013, // 11 000 0000 0010 011 + ARM64_SYSREG_ID_ISAR4_EL1 = 0xc014, // 11 000 0000 0010 100 + ARM64_SYSREG_ID_ISAR5_EL1 = 0xc015, // 11 000 0000 0010 101 + ARM64_SYSREG_ID_A64PFR0_EL1 = 0xc020, // 11 000 0000 0100 000 + ARM64_SYSREG_ID_A64PFR1_EL1 = 0xc021, // 11 000 0000 0100 001 + ARM64_SYSREG_ID_A64DFR0_EL1 = 0xc028, // 11 000 0000 0101 000 + ARM64_SYSREG_ID_A64DFR1_EL1 = 0xc029, // 11 000 0000 0101 001 + ARM64_SYSREG_ID_A64AFR0_EL1 = 0xc02c, // 11 000 0000 0101 100 + ARM64_SYSREG_ID_A64AFR1_EL1 = 0xc02d, // 11 000 0000 0101 101 + ARM64_SYSREG_ID_A64ISAR0_EL1 = 0xc030, // 11 000 0000 0110 000 + ARM64_SYSREG_ID_A64ISAR1_EL1 = 0xc031, // 11 000 0000 0110 001 + ARM64_SYSREG_ID_A64MMFR0_EL1 = 0xc038, // 11 000 0000 0111 000 + ARM64_SYSREG_ID_A64MMFR1_EL1 = 0xc039, // 11 000 0000 0111 001 + ARM64_SYSREG_MVFR0_EL1 = 0xc018, // 11 000 0000 0011 000 + ARM64_SYSREG_MVFR1_EL1 = 0xc019, // 11 000 0000 0011 001 + ARM64_SYSREG_MVFR2_EL1 = 0xc01a, // 11 000 0000 0011 010 + ARM64_SYSREG_RVBAR_EL1 = 0xc601, // 11 000 1100 0000 001 + ARM64_SYSREG_RVBAR_EL2 = 0xe601, // 11 100 1100 0000 001 + ARM64_SYSREG_RVBAR_EL3 = 0xf601, // 11 110 1100 0000 001 + ARM64_SYSREG_ISR_EL1 = 0xc608, // 11 000 1100 0001 000 + ARM64_SYSREG_CNTPCT_EL0 = 0xdf01, // 11 011 1110 0000 001 + ARM64_SYSREG_CNTVCT_EL0 = 0xdf02, // 11 011 1110 0000 010 + + // Trace registers + ARM64_SYSREG_TRCSTATR = 0x8818, // 10 001 0000 0011 000 + ARM64_SYSREG_TRCIDR8 = 0x8806, // 10 001 0000 0000 110 + ARM64_SYSREG_TRCIDR9 = 0x880e, // 10 001 0000 0001 110 + ARM64_SYSREG_TRCIDR10 = 0x8816, // 10 001 0000 0010 110 + ARM64_SYSREG_TRCIDR11 = 0x881e, // 10 001 0000 0011 110 + ARM64_SYSREG_TRCIDR12 = 0x8826, // 10 001 0000 0100 110 + ARM64_SYSREG_TRCIDR13 = 0x882e, // 10 001 0000 0101 110 + ARM64_SYSREG_TRCIDR0 = 0x8847, // 10 001 0000 1000 111 + ARM64_SYSREG_TRCIDR1 = 0x884f, // 10 001 0000 1001 111 + ARM64_SYSREG_TRCIDR2 = 0x8857, // 10 001 0000 1010 111 + ARM64_SYSREG_TRCIDR3 = 0x885f, // 10 001 0000 1011 111 + ARM64_SYSREG_TRCIDR4 = 0x8867, // 10 001 0000 1100 111 + ARM64_SYSREG_TRCIDR5 = 0x886f, // 10 001 0000 1101 111 + ARM64_SYSREG_TRCIDR6 = 0x8877, // 10 001 0000 1110 111 + ARM64_SYSREG_TRCIDR7 = 0x887f, // 10 001 0000 1111 111 + ARM64_SYSREG_TRCOSLSR = 0x888c, // 10 001 0001 0001 100 + ARM64_SYSREG_TRCPDSR = 0x88ac, // 10 001 0001 0101 100 + ARM64_SYSREG_TRCDEVAFF0 = 0x8bd6, // 10 001 0111 1010 110 + ARM64_SYSREG_TRCDEVAFF1 = 0x8bde, // 10 001 0111 1011 110 + ARM64_SYSREG_TRCLSR = 0x8bee, // 10 001 0111 1101 110 + ARM64_SYSREG_TRCAUTHSTATUS = 0x8bf6, // 10 001 0111 1110 110 + ARM64_SYSREG_TRCDEVARCH = 0x8bfe, // 10 001 0111 1111 110 + ARM64_SYSREG_TRCDEVID = 0x8b97, // 10 001 0111 0010 111 + ARM64_SYSREG_TRCDEVTYPE = 0x8b9f, // 10 001 0111 0011 111 + ARM64_SYSREG_TRCPIDR4 = 0x8ba7, // 10 001 0111 0100 111 + ARM64_SYSREG_TRCPIDR5 = 0x8baf, // 10 001 0111 0101 111 + ARM64_SYSREG_TRCPIDR6 = 0x8bb7, // 10 001 0111 0110 111 + ARM64_SYSREG_TRCPIDR7 = 0x8bbf, // 10 001 0111 0111 111 + ARM64_SYSREG_TRCPIDR0 = 0x8bc7, // 10 001 0111 1000 111 + ARM64_SYSREG_TRCPIDR1 = 0x8bcf, // 10 001 0111 1001 111 + ARM64_SYSREG_TRCPIDR2 = 0x8bd7, // 10 001 0111 1010 111 + ARM64_SYSREG_TRCPIDR3 = 0x8bdf, // 10 001 0111 1011 111 + ARM64_SYSREG_TRCCIDR0 = 0x8be7, // 10 001 0111 1100 111 + ARM64_SYSREG_TRCCIDR1 = 0x8bef, // 10 001 0111 1101 111 + ARM64_SYSREG_TRCCIDR2 = 0x8bf7, // 10 001 0111 1110 111 + ARM64_SYSREG_TRCCIDR3 = 0x8bff, // 10 001 0111 1111 111 + + // GICv3 registers + ARM64_SYSREG_ICC_IAR1_EL1 = 0xc660, // 11 000 1100 1100 000 + ARM64_SYSREG_ICC_IAR0_EL1 = 0xc640, // 11 000 1100 1000 000 + ARM64_SYSREG_ICC_HPPIR1_EL1 = 0xc662, // 11 000 1100 1100 010 + ARM64_SYSREG_ICC_HPPIR0_EL1 = 0xc642, // 11 000 1100 1000 010 + ARM64_SYSREG_ICC_RPR_EL1 = 0xc65b, // 11 000 1100 1011 011 + ARM64_SYSREG_ICH_VTR_EL2 = 0xe659, // 11 100 1100 1011 001 + ARM64_SYSREG_ICH_EISR_EL2 = 0xe65b, // 11 100 1100 1011 011 + ARM64_SYSREG_ICH_ELSR_EL2 = 0xe65d, // 11 100 1100 1011 101 +} arm64_sysreg; + +typedef enum arm64_msr_reg { + //> System registers for MSR + ARM64_SYSREG_DBGDTRTX_EL0 = 0x9828, // 10 011 0000 0101 000 + ARM64_SYSREG_OSLAR_EL1 = 0x8084, // 10 000 0001 0000 100 + ARM64_SYSREG_PMSWINC_EL0 = 0xdce4, // 11 011 1001 1100 100 + + // Trace Registers + ARM64_SYSREG_TRCOSLAR = 0x8884, // 10 001 0001 0000 100 + ARM64_SYSREG_TRCLAR = 0x8be6, // 10 001 0111 1100 110 + + // GICv3 registers + ARM64_SYSREG_ICC_EOIR1_EL1 = 0xc661, // 11 000 1100 1100 001 + ARM64_SYSREG_ICC_EOIR0_EL1 = 0xc641, // 11 000 1100 1000 001 + ARM64_SYSREG_ICC_DIR_EL1 = 0xc659, // 11 000 1100 1011 001 + ARM64_SYSREG_ICC_SGI1R_EL1 = 0xc65d, // 11 000 1100 1011 101 + ARM64_SYSREG_ICC_ASGI1R_EL1 = 0xc65e, // 11 000 1100 1011 110 + ARM64_SYSREG_ICC_SGI0R_EL1 = 0xc65f, // 11 000 1100 1011 111 +} arm64_msr_reg; + +//> System PState Field (MSR instruction) +typedef enum arm64_pstate { + ARM64_PSTATE_INVALID = 0, + ARM64_PSTATE_SPSEL = 0x05, + ARM64_PSTATE_DAIFSET = 0x1e, + ARM64_PSTATE_DAIFCLR = 0x1f +} arm64_pstate; + +//> Vector arrangement specifier (for FloatingPoint/Advanced SIMD insn) +typedef enum arm64_vas { + ARM64_VAS_INVALID = 0, + ARM64_VAS_8B, + ARM64_VAS_16B, + ARM64_VAS_4H, + ARM64_VAS_8H, + ARM64_VAS_2S, + ARM64_VAS_4S, + ARM64_VAS_1D, + ARM64_VAS_2D, + ARM64_VAS_1Q, +} arm64_vas; + +//> Vector element size specifier +typedef enum arm64_vess { + ARM64_VESS_INVALID = 0, + ARM64_VESS_B, + ARM64_VESS_H, + ARM64_VESS_S, + ARM64_VESS_D, +} arm64_vess; + +//> Memory barrier operands +typedef enum arm64_barrier_op { + ARM64_BARRIER_INVALID = 0, + ARM64_BARRIER_OSHLD = 0x1, + ARM64_BARRIER_OSHST = 0x2, + ARM64_BARRIER_OSH = 0x3, + ARM64_BARRIER_NSHLD = 0x5, + ARM64_BARRIER_NSHST = 0x6, + ARM64_BARRIER_NSH = 0x7, + ARM64_BARRIER_ISHLD = 0x9, + ARM64_BARRIER_ISHST = 0xa, + ARM64_BARRIER_ISH = 0xb, + ARM64_BARRIER_LD = 0xd, + ARM64_BARRIER_ST = 0xe, + ARM64_BARRIER_SY = 0xf +} arm64_barrier_op; + +//> Operand type for instruction's operands +typedef enum arm64_op_type { + ARM64_OP_INVALID = 0, // = CS_OP_INVALID (Uninitialized). + ARM64_OP_REG, // = CS_OP_REG (Register operand). + ARM64_OP_IMM, // = CS_OP_IMM (Immediate operand). + ARM64_OP_MEM, // = CS_OP_MEM (Memory operand). + ARM64_OP_FP, // = CS_OP_FP (Floating-Point operand). + ARM64_OP_CIMM = 64, // C-Immediate + ARM64_OP_REG_MRS, // MRS register operand. + ARM64_OP_REG_MSR, // MSR register operand. + ARM64_OP_PSTATE, // PState operand. + ARM64_OP_SYS, // SYS operand for IC/DC/AT/TLBI instructions. + ARM64_OP_PREFETCH, // Prefetch operand (PRFM). + ARM64_OP_BARRIER, // Memory barrier operand (ISB/DMB/DSB instructions). +} arm64_op_type; + +//> TLBI operations +typedef enum arm64_tlbi_op { + ARM64_TLBI_INVALID = 0, + ARM64_TLBI_VMALLE1IS, + ARM64_TLBI_VAE1IS, + ARM64_TLBI_ASIDE1IS, + ARM64_TLBI_VAAE1IS, + ARM64_TLBI_VALE1IS, + ARM64_TLBI_VAALE1IS, + ARM64_TLBI_ALLE2IS, + ARM64_TLBI_VAE2IS, + ARM64_TLBI_ALLE1IS, + ARM64_TLBI_VALE2IS, + ARM64_TLBI_VMALLS12E1IS, + ARM64_TLBI_ALLE3IS, + ARM64_TLBI_VAE3IS, + ARM64_TLBI_VALE3IS, + ARM64_TLBI_IPAS2E1IS, + ARM64_TLBI_IPAS2LE1IS, + ARM64_TLBI_IPAS2E1, + ARM64_TLBI_IPAS2LE1, + ARM64_TLBI_VMALLE1, + ARM64_TLBI_VAE1, + ARM64_TLBI_ASIDE1, + ARM64_TLBI_VAAE1, + ARM64_TLBI_VALE1, + ARM64_TLBI_VAALE1, + ARM64_TLBI_ALLE2, + ARM64_TLBI_VAE2, + ARM64_TLBI_ALLE1, + ARM64_TLBI_VALE2, + ARM64_TLBI_VMALLS12E1, + ARM64_TLBI_ALLE3, + ARM64_TLBI_VAE3, + ARM64_TLBI_VALE3, +} arm64_tlbi_op; + +//> AT operations +typedef enum arm64_at_op { + ARM64_AT_S1E1R, + ARM64_AT_S1E1W, + ARM64_AT_S1E0R, + ARM64_AT_S1E0W, + ARM64_AT_S1E2R, + ARM64_AT_S1E2W, + ARM64_AT_S12E1R, + ARM64_AT_S12E1W, + ARM64_AT_S12E0R, + ARM64_AT_S12E0W, + ARM64_AT_S1E3R, + ARM64_AT_S1E3W, +} arm64_at_op; + +//> DC operations +typedef enum arm64_dc_op { + ARM64_DC_INVALID = 0, + ARM64_DC_ZVA, + ARM64_DC_IVAC, + ARM64_DC_ISW, + ARM64_DC_CVAC, + ARM64_DC_CSW, + ARM64_DC_CVAU, + ARM64_DC_CIVAC, + ARM64_DC_CISW, +} arm64_dc_op; + +//> IC operations +typedef enum arm64_ic_op { + ARM64_IC_INVALID = 0, + ARM64_IC_IALLUIS, + ARM64_IC_IALLU, + ARM64_IC_IVAU, +} arm64_ic_op; + +//> Prefetch operations (PRFM) +typedef enum arm64_prefetch_op { + ARM64_PRFM_INVALID = 0, + ARM64_PRFM_PLDL1KEEP = 0x00 + 1, + ARM64_PRFM_PLDL1STRM = 0x01 + 1, + ARM64_PRFM_PLDL2KEEP = 0x02 + 1, + ARM64_PRFM_PLDL2STRM = 0x03 + 1, + ARM64_PRFM_PLDL3KEEP = 0x04 + 1, + ARM64_PRFM_PLDL3STRM = 0x05 + 1, + ARM64_PRFM_PLIL1KEEP = 0x08 + 1, + ARM64_PRFM_PLIL1STRM = 0x09 + 1, + ARM64_PRFM_PLIL2KEEP = 0x0a + 1, + ARM64_PRFM_PLIL2STRM = 0x0b + 1, + ARM64_PRFM_PLIL3KEEP = 0x0c + 1, + ARM64_PRFM_PLIL3STRM = 0x0d + 1, + ARM64_PRFM_PSTL1KEEP = 0x10 + 1, + ARM64_PRFM_PSTL1STRM = 0x11 + 1, + ARM64_PRFM_PSTL2KEEP = 0x12 + 1, + ARM64_PRFM_PSTL2STRM = 0x13 + 1, + ARM64_PRFM_PSTL3KEEP = 0x14 + 1, + ARM64_PRFM_PSTL3STRM = 0x15 + 1, +} arm64_prefetch_op; + +// Instruction's operand referring to memory +// This is associated with ARM64_OP_MEM operand type above +typedef struct arm64_op_mem { + unsigned int base; // base register + unsigned int index; // index register + int32_t disp; // displacement/offset value +} arm64_op_mem; + +// Instruction operand +typedef struct cs_arm64_op { + int vector_index; // Vector Index for some vector operands (or -1 if irrelevant) + arm64_vas vas; // Vector Arrangement Specifier + arm64_vess vess; // Vector Element Size Specifier + struct { + arm64_shifter type; // shifter type of this operand + unsigned int value; // shifter value of this operand + } shift; + arm64_extender ext; // extender type of this operand + arm64_op_type type; // operand type + union { + unsigned int reg; // register value for REG operand + int64_t imm; // immediate value, or index for C-IMM or IMM operand + double fp; // floating point value for FP operand + arm64_op_mem mem; // base/index/scale/disp value for MEM operand + arm64_pstate pstate; // PState field of MSR instruction. + unsigned int sys; // IC/DC/AT/TLBI operation (see arm64_ic_op, arm64_dc_op, arm64_at_op, arm64_tlbi_op) + arm64_prefetch_op prefetch; // PRFM operation. + arm64_barrier_op barrier; // Memory barrier operation (ISB/DMB/DSB instructions). + }; +} cs_arm64_op; + +// Instruction structure +typedef struct cs_arm64 { + arm64_cc cc; // conditional code for this insn + bool update_flags; // does this insn update flags? + bool writeback; // does this insn request writeback? 'True' means 'yes' + + // Number of operands of this instruction, + // or 0 when instruction has no operand. + uint8_t op_count; + + cs_arm64_op operands[8]; // operands for this instruction. +} cs_arm64; + +//> ARM64 registers +typedef enum arm64_reg { + ARM64_REG_INVALID = 0, + + ARM64_REG_X29, + ARM64_REG_X30, + ARM64_REG_NZCV, + ARM64_REG_SP, + ARM64_REG_WSP, + ARM64_REG_WZR, + ARM64_REG_XZR, + ARM64_REG_B0, + ARM64_REG_B1, + ARM64_REG_B2, + ARM64_REG_B3, + ARM64_REG_B4, + ARM64_REG_B5, + ARM64_REG_B6, + ARM64_REG_B7, + ARM64_REG_B8, + ARM64_REG_B9, + ARM64_REG_B10, + ARM64_REG_B11, + ARM64_REG_B12, + ARM64_REG_B13, + ARM64_REG_B14, + ARM64_REG_B15, + ARM64_REG_B16, + ARM64_REG_B17, + ARM64_REG_B18, + ARM64_REG_B19, + ARM64_REG_B20, + ARM64_REG_B21, + ARM64_REG_B22, + ARM64_REG_B23, + ARM64_REG_B24, + ARM64_REG_B25, + ARM64_REG_B26, + ARM64_REG_B27, + ARM64_REG_B28, + ARM64_REG_B29, + ARM64_REG_B30, + ARM64_REG_B31, + ARM64_REG_D0, + ARM64_REG_D1, + ARM64_REG_D2, + ARM64_REG_D3, + ARM64_REG_D4, + ARM64_REG_D5, + ARM64_REG_D6, + ARM64_REG_D7, + ARM64_REG_D8, + ARM64_REG_D9, + ARM64_REG_D10, + ARM64_REG_D11, + ARM64_REG_D12, + ARM64_REG_D13, + ARM64_REG_D14, + ARM64_REG_D15, + ARM64_REG_D16, + ARM64_REG_D17, + ARM64_REG_D18, + ARM64_REG_D19, + ARM64_REG_D20, + ARM64_REG_D21, + ARM64_REG_D22, + ARM64_REG_D23, + ARM64_REG_D24, + ARM64_REG_D25, + ARM64_REG_D26, + ARM64_REG_D27, + ARM64_REG_D28, + ARM64_REG_D29, + ARM64_REG_D30, + ARM64_REG_D31, + ARM64_REG_H0, + ARM64_REG_H1, + ARM64_REG_H2, + ARM64_REG_H3, + ARM64_REG_H4, + ARM64_REG_H5, + ARM64_REG_H6, + ARM64_REG_H7, + ARM64_REG_H8, + ARM64_REG_H9, + ARM64_REG_H10, + ARM64_REG_H11, + ARM64_REG_H12, + ARM64_REG_H13, + ARM64_REG_H14, + ARM64_REG_H15, + ARM64_REG_H16, + ARM64_REG_H17, + ARM64_REG_H18, + ARM64_REG_H19, + ARM64_REG_H20, + ARM64_REG_H21, + ARM64_REG_H22, + ARM64_REG_H23, + ARM64_REG_H24, + ARM64_REG_H25, + ARM64_REG_H26, + ARM64_REG_H27, + ARM64_REG_H28, + ARM64_REG_H29, + ARM64_REG_H30, + ARM64_REG_H31, + ARM64_REG_Q0, + ARM64_REG_Q1, + ARM64_REG_Q2, + ARM64_REG_Q3, + ARM64_REG_Q4, + ARM64_REG_Q5, + ARM64_REG_Q6, + ARM64_REG_Q7, + ARM64_REG_Q8, + ARM64_REG_Q9, + ARM64_REG_Q10, + ARM64_REG_Q11, + ARM64_REG_Q12, + ARM64_REG_Q13, + ARM64_REG_Q14, + ARM64_REG_Q15, + ARM64_REG_Q16, + ARM64_REG_Q17, + ARM64_REG_Q18, + ARM64_REG_Q19, + ARM64_REG_Q20, + ARM64_REG_Q21, + ARM64_REG_Q22, + ARM64_REG_Q23, + ARM64_REG_Q24, + ARM64_REG_Q25, + ARM64_REG_Q26, + ARM64_REG_Q27, + ARM64_REG_Q28, + ARM64_REG_Q29, + ARM64_REG_Q30, + ARM64_REG_Q31, + ARM64_REG_S0, + ARM64_REG_S1, + ARM64_REG_S2, + ARM64_REG_S3, + ARM64_REG_S4, + ARM64_REG_S5, + ARM64_REG_S6, + ARM64_REG_S7, + ARM64_REG_S8, + ARM64_REG_S9, + ARM64_REG_S10, + ARM64_REG_S11, + ARM64_REG_S12, + ARM64_REG_S13, + ARM64_REG_S14, + ARM64_REG_S15, + ARM64_REG_S16, + ARM64_REG_S17, + ARM64_REG_S18, + ARM64_REG_S19, + ARM64_REG_S20, + ARM64_REG_S21, + ARM64_REG_S22, + ARM64_REG_S23, + ARM64_REG_S24, + ARM64_REG_S25, + ARM64_REG_S26, + ARM64_REG_S27, + ARM64_REG_S28, + ARM64_REG_S29, + ARM64_REG_S30, + ARM64_REG_S31, + ARM64_REG_W0, + ARM64_REG_W1, + ARM64_REG_W2, + ARM64_REG_W3, + ARM64_REG_W4, + ARM64_REG_W5, + ARM64_REG_W6, + ARM64_REG_W7, + ARM64_REG_W8, + ARM64_REG_W9, + ARM64_REG_W10, + ARM64_REG_W11, + ARM64_REG_W12, + ARM64_REG_W13, + ARM64_REG_W14, + ARM64_REG_W15, + ARM64_REG_W16, + ARM64_REG_W17, + ARM64_REG_W18, + ARM64_REG_W19, + ARM64_REG_W20, + ARM64_REG_W21, + ARM64_REG_W22, + ARM64_REG_W23, + ARM64_REG_W24, + ARM64_REG_W25, + ARM64_REG_W26, + ARM64_REG_W27, + ARM64_REG_W28, + ARM64_REG_W29, + ARM64_REG_W30, + ARM64_REG_X0, + ARM64_REG_X1, + ARM64_REG_X2, + ARM64_REG_X3, + ARM64_REG_X4, + ARM64_REG_X5, + ARM64_REG_X6, + ARM64_REG_X7, + ARM64_REG_X8, + ARM64_REG_X9, + ARM64_REG_X10, + ARM64_REG_X11, + ARM64_REG_X12, + ARM64_REG_X13, + ARM64_REG_X14, + ARM64_REG_X15, + ARM64_REG_X16, + ARM64_REG_X17, + ARM64_REG_X18, + ARM64_REG_X19, + ARM64_REG_X20, + ARM64_REG_X21, + ARM64_REG_X22, + ARM64_REG_X23, + ARM64_REG_X24, + ARM64_REG_X25, + ARM64_REG_X26, + ARM64_REG_X27, + ARM64_REG_X28, + + ARM64_REG_V0, + ARM64_REG_V1, + ARM64_REG_V2, + ARM64_REG_V3, + ARM64_REG_V4, + ARM64_REG_V5, + ARM64_REG_V6, + ARM64_REG_V7, + ARM64_REG_V8, + ARM64_REG_V9, + ARM64_REG_V10, + ARM64_REG_V11, + ARM64_REG_V12, + ARM64_REG_V13, + ARM64_REG_V14, + ARM64_REG_V15, + ARM64_REG_V16, + ARM64_REG_V17, + ARM64_REG_V18, + ARM64_REG_V19, + ARM64_REG_V20, + ARM64_REG_V21, + ARM64_REG_V22, + ARM64_REG_V23, + ARM64_REG_V24, + ARM64_REG_V25, + ARM64_REG_V26, + ARM64_REG_V27, + ARM64_REG_V28, + ARM64_REG_V29, + ARM64_REG_V30, + ARM64_REG_V31, + + ARM64_REG_ENDING, // <-- mark the end of the list of registers + + //> alias registers + + ARM64_REG_IP1 = ARM64_REG_X16, + ARM64_REG_IP0 = ARM64_REG_X17, + ARM64_REG_FP = ARM64_REG_X29, + ARM64_REG_LR = ARM64_REG_X30, +} arm64_reg; + +//> ARM64 instruction +typedef enum arm64_insn { + ARM64_INS_INVALID = 0, + + ARM64_INS_ABS, + ARM64_INS_ADC, + ARM64_INS_ADDHN, + ARM64_INS_ADDHN2, + ARM64_INS_ADDP, + ARM64_INS_ADD, + ARM64_INS_ADDV, + ARM64_INS_ADR, + ARM64_INS_ADRP, + ARM64_INS_AESD, + ARM64_INS_AESE, + ARM64_INS_AESIMC, + ARM64_INS_AESMC, + ARM64_INS_AND, + ARM64_INS_ASR, + ARM64_INS_B, + ARM64_INS_BFM, + ARM64_INS_BIC, + ARM64_INS_BIF, + ARM64_INS_BIT, + ARM64_INS_BL, + ARM64_INS_BLR, + ARM64_INS_BR, + ARM64_INS_BRK, + ARM64_INS_BSL, + ARM64_INS_CBNZ, + ARM64_INS_CBZ, + ARM64_INS_CCMN, + ARM64_INS_CCMP, + ARM64_INS_CLREX, + ARM64_INS_CLS, + ARM64_INS_CLZ, + ARM64_INS_CMEQ, + ARM64_INS_CMGE, + ARM64_INS_CMGT, + ARM64_INS_CMHI, + ARM64_INS_CMHS, + ARM64_INS_CMLE, + ARM64_INS_CMLT, + ARM64_INS_CMTST, + ARM64_INS_CNT, + ARM64_INS_MOV, + ARM64_INS_CRC32B, + ARM64_INS_CRC32CB, + ARM64_INS_CRC32CH, + ARM64_INS_CRC32CW, + ARM64_INS_CRC32CX, + ARM64_INS_CRC32H, + ARM64_INS_CRC32W, + ARM64_INS_CRC32X, + ARM64_INS_CSEL, + ARM64_INS_CSINC, + ARM64_INS_CSINV, + ARM64_INS_CSNEG, + ARM64_INS_DCPS1, + ARM64_INS_DCPS2, + ARM64_INS_DCPS3, + ARM64_INS_DMB, + ARM64_INS_DRPS, + ARM64_INS_DSB, + ARM64_INS_DUP, + ARM64_INS_EON, + ARM64_INS_EOR, + ARM64_INS_ERET, + ARM64_INS_EXTR, + ARM64_INS_EXT, + ARM64_INS_FABD, + ARM64_INS_FABS, + ARM64_INS_FACGE, + ARM64_INS_FACGT, + ARM64_INS_FADD, + ARM64_INS_FADDP, + ARM64_INS_FCCMP, + ARM64_INS_FCCMPE, + ARM64_INS_FCMEQ, + ARM64_INS_FCMGE, + ARM64_INS_FCMGT, + ARM64_INS_FCMLE, + ARM64_INS_FCMLT, + ARM64_INS_FCMP, + ARM64_INS_FCMPE, + ARM64_INS_FCSEL, + ARM64_INS_FCVTAS, + ARM64_INS_FCVTAU, + ARM64_INS_FCVT, + ARM64_INS_FCVTL, + ARM64_INS_FCVTL2, + ARM64_INS_FCVTMS, + ARM64_INS_FCVTMU, + ARM64_INS_FCVTNS, + ARM64_INS_FCVTNU, + ARM64_INS_FCVTN, + ARM64_INS_FCVTN2, + ARM64_INS_FCVTPS, + ARM64_INS_FCVTPU, + ARM64_INS_FCVTXN, + ARM64_INS_FCVTXN2, + ARM64_INS_FCVTZS, + ARM64_INS_FCVTZU, + ARM64_INS_FDIV, + ARM64_INS_FMADD, + ARM64_INS_FMAX, + ARM64_INS_FMAXNM, + ARM64_INS_FMAXNMP, + ARM64_INS_FMAXNMV, + ARM64_INS_FMAXP, + ARM64_INS_FMAXV, + ARM64_INS_FMIN, + ARM64_INS_FMINNM, + ARM64_INS_FMINNMP, + ARM64_INS_FMINNMV, + ARM64_INS_FMINP, + ARM64_INS_FMINV, + ARM64_INS_FMLA, + ARM64_INS_FMLS, + ARM64_INS_FMOV, + ARM64_INS_FMSUB, + ARM64_INS_FMUL, + ARM64_INS_FMULX, + ARM64_INS_FNEG, + ARM64_INS_FNMADD, + ARM64_INS_FNMSUB, + ARM64_INS_FNMUL, + ARM64_INS_FRECPE, + ARM64_INS_FRECPS, + ARM64_INS_FRECPX, + ARM64_INS_FRINTA, + ARM64_INS_FRINTI, + ARM64_INS_FRINTM, + ARM64_INS_FRINTN, + ARM64_INS_FRINTP, + ARM64_INS_FRINTX, + ARM64_INS_FRINTZ, + ARM64_INS_FRSQRTE, + ARM64_INS_FRSQRTS, + ARM64_INS_FSQRT, + ARM64_INS_FSUB, + ARM64_INS_HINT, + ARM64_INS_HLT, + ARM64_INS_HVC, + ARM64_INS_INS, + + ARM64_INS_ISB, + ARM64_INS_LD1, + ARM64_INS_LD1R, + ARM64_INS_LD2R, + ARM64_INS_LD2, + ARM64_INS_LD3R, + ARM64_INS_LD3, + ARM64_INS_LD4, + ARM64_INS_LD4R, + + ARM64_INS_LDARB, + ARM64_INS_LDARH, + ARM64_INS_LDAR, + ARM64_INS_LDAXP, + ARM64_INS_LDAXRB, + ARM64_INS_LDAXRH, + ARM64_INS_LDAXR, + ARM64_INS_LDNP, + ARM64_INS_LDP, + ARM64_INS_LDPSW, + ARM64_INS_LDRB, + ARM64_INS_LDR, + ARM64_INS_LDRH, + ARM64_INS_LDRSB, + ARM64_INS_LDRSH, + ARM64_INS_LDRSW, + ARM64_INS_LDTRB, + ARM64_INS_LDTRH, + ARM64_INS_LDTRSB, + + ARM64_INS_LDTRSH, + ARM64_INS_LDTRSW, + ARM64_INS_LDTR, + ARM64_INS_LDURB, + ARM64_INS_LDUR, + ARM64_INS_LDURH, + ARM64_INS_LDURSB, + ARM64_INS_LDURSH, + ARM64_INS_LDURSW, + ARM64_INS_LDXP, + ARM64_INS_LDXRB, + ARM64_INS_LDXRH, + ARM64_INS_LDXR, + ARM64_INS_LSL, + ARM64_INS_LSR, + ARM64_INS_MADD, + ARM64_INS_MLA, + ARM64_INS_MLS, + ARM64_INS_MOVI, + ARM64_INS_MOVK, + ARM64_INS_MOVN, + ARM64_INS_MOVZ, + ARM64_INS_MRS, + ARM64_INS_MSR, + ARM64_INS_MSUB, + ARM64_INS_MUL, + ARM64_INS_MVNI, + ARM64_INS_NEG, + ARM64_INS_NOT, + ARM64_INS_ORN, + ARM64_INS_ORR, + ARM64_INS_PMULL2, + ARM64_INS_PMULL, + ARM64_INS_PMUL, + ARM64_INS_PRFM, + ARM64_INS_PRFUM, + ARM64_INS_RADDHN, + ARM64_INS_RADDHN2, + ARM64_INS_RBIT, + ARM64_INS_RET, + ARM64_INS_REV16, + ARM64_INS_REV32, + ARM64_INS_REV64, + ARM64_INS_REV, + ARM64_INS_ROR, + ARM64_INS_RSHRN2, + ARM64_INS_RSHRN, + ARM64_INS_RSUBHN, + ARM64_INS_RSUBHN2, + ARM64_INS_SABAL2, + ARM64_INS_SABAL, + + ARM64_INS_SABA, + ARM64_INS_SABDL2, + ARM64_INS_SABDL, + ARM64_INS_SABD, + ARM64_INS_SADALP, + ARM64_INS_SADDLP, + ARM64_INS_SADDLV, + ARM64_INS_SADDL2, + ARM64_INS_SADDL, + ARM64_INS_SADDW2, + ARM64_INS_SADDW, + ARM64_INS_SBC, + ARM64_INS_SBFM, + ARM64_INS_SCVTF, + ARM64_INS_SDIV, + ARM64_INS_SHA1C, + ARM64_INS_SHA1H, + ARM64_INS_SHA1M, + ARM64_INS_SHA1P, + ARM64_INS_SHA1SU0, + ARM64_INS_SHA1SU1, + ARM64_INS_SHA256H2, + ARM64_INS_SHA256H, + ARM64_INS_SHA256SU0, + ARM64_INS_SHA256SU1, + ARM64_INS_SHADD, + ARM64_INS_SHLL2, + ARM64_INS_SHLL, + ARM64_INS_SHL, + ARM64_INS_SHRN2, + ARM64_INS_SHRN, + ARM64_INS_SHSUB, + ARM64_INS_SLI, + ARM64_INS_SMADDL, + ARM64_INS_SMAXP, + ARM64_INS_SMAXV, + ARM64_INS_SMAX, + ARM64_INS_SMC, + ARM64_INS_SMINP, + ARM64_INS_SMINV, + ARM64_INS_SMIN, + ARM64_INS_SMLAL2, + ARM64_INS_SMLAL, + ARM64_INS_SMLSL2, + ARM64_INS_SMLSL, + ARM64_INS_SMOV, + ARM64_INS_SMSUBL, + ARM64_INS_SMULH, + ARM64_INS_SMULL2, + ARM64_INS_SMULL, + ARM64_INS_SQABS, + ARM64_INS_SQADD, + ARM64_INS_SQDMLAL, + ARM64_INS_SQDMLAL2, + ARM64_INS_SQDMLSL, + ARM64_INS_SQDMLSL2, + ARM64_INS_SQDMULH, + ARM64_INS_SQDMULL, + ARM64_INS_SQDMULL2, + ARM64_INS_SQNEG, + ARM64_INS_SQRDMULH, + ARM64_INS_SQRSHL, + ARM64_INS_SQRSHRN, + ARM64_INS_SQRSHRN2, + ARM64_INS_SQRSHRUN, + ARM64_INS_SQRSHRUN2, + ARM64_INS_SQSHLU, + ARM64_INS_SQSHL, + ARM64_INS_SQSHRN, + ARM64_INS_SQSHRN2, + ARM64_INS_SQSHRUN, + ARM64_INS_SQSHRUN2, + ARM64_INS_SQSUB, + ARM64_INS_SQXTN2, + ARM64_INS_SQXTN, + ARM64_INS_SQXTUN2, + ARM64_INS_SQXTUN, + ARM64_INS_SRHADD, + ARM64_INS_SRI, + ARM64_INS_SRSHL, + ARM64_INS_SRSHR, + ARM64_INS_SRSRA, + ARM64_INS_SSHLL2, + ARM64_INS_SSHLL, + ARM64_INS_SSHL, + ARM64_INS_SSHR, + ARM64_INS_SSRA, + ARM64_INS_SSUBL2, + ARM64_INS_SSUBL, + ARM64_INS_SSUBW2, + ARM64_INS_SSUBW, + ARM64_INS_ST1, + ARM64_INS_ST2, + ARM64_INS_ST3, + ARM64_INS_ST4, + ARM64_INS_STLRB, + ARM64_INS_STLRH, + ARM64_INS_STLR, + ARM64_INS_STLXP, + ARM64_INS_STLXRB, + ARM64_INS_STLXRH, + ARM64_INS_STLXR, + ARM64_INS_STNP, + ARM64_INS_STP, + ARM64_INS_STRB, + ARM64_INS_STR, + ARM64_INS_STRH, + ARM64_INS_STTRB, + ARM64_INS_STTRH, + ARM64_INS_STTR, + ARM64_INS_STURB, + ARM64_INS_STUR, + ARM64_INS_STURH, + ARM64_INS_STXP, + ARM64_INS_STXRB, + ARM64_INS_STXRH, + ARM64_INS_STXR, + ARM64_INS_SUBHN, + ARM64_INS_SUBHN2, + ARM64_INS_SUB, + ARM64_INS_SUQADD, + ARM64_INS_SVC, + ARM64_INS_SYSL, + ARM64_INS_SYS, + ARM64_INS_TBL, + ARM64_INS_TBNZ, + ARM64_INS_TBX, + ARM64_INS_TBZ, + ARM64_INS_TRN1, + ARM64_INS_TRN2, + ARM64_INS_UABAL2, + ARM64_INS_UABAL, + ARM64_INS_UABA, + ARM64_INS_UABDL2, + ARM64_INS_UABDL, + ARM64_INS_UABD, + ARM64_INS_UADALP, + ARM64_INS_UADDLP, + ARM64_INS_UADDLV, + ARM64_INS_UADDL2, + ARM64_INS_UADDL, + ARM64_INS_UADDW2, + ARM64_INS_UADDW, + ARM64_INS_UBFM, + ARM64_INS_UCVTF, + ARM64_INS_UDIV, + ARM64_INS_UHADD, + ARM64_INS_UHSUB, + ARM64_INS_UMADDL, + ARM64_INS_UMAXP, + ARM64_INS_UMAXV, + ARM64_INS_UMAX, + ARM64_INS_UMINP, + ARM64_INS_UMINV, + ARM64_INS_UMIN, + ARM64_INS_UMLAL2, + ARM64_INS_UMLAL, + ARM64_INS_UMLSL2, + ARM64_INS_UMLSL, + ARM64_INS_UMOV, + ARM64_INS_UMSUBL, + ARM64_INS_UMULH, + ARM64_INS_UMULL2, + ARM64_INS_UMULL, + ARM64_INS_UQADD, + ARM64_INS_UQRSHL, + ARM64_INS_UQRSHRN, + ARM64_INS_UQRSHRN2, + ARM64_INS_UQSHL, + ARM64_INS_UQSHRN, + ARM64_INS_UQSHRN2, + ARM64_INS_UQSUB, + ARM64_INS_UQXTN2, + ARM64_INS_UQXTN, + ARM64_INS_URECPE, + ARM64_INS_URHADD, + ARM64_INS_URSHL, + ARM64_INS_URSHR, + ARM64_INS_URSQRTE, + ARM64_INS_URSRA, + ARM64_INS_USHLL2, + ARM64_INS_USHLL, + ARM64_INS_USHL, + ARM64_INS_USHR, + ARM64_INS_USQADD, + ARM64_INS_USRA, + ARM64_INS_USUBL2, + ARM64_INS_USUBL, + ARM64_INS_USUBW2, + ARM64_INS_USUBW, + ARM64_INS_UZP1, + ARM64_INS_UZP2, + ARM64_INS_XTN2, + ARM64_INS_XTN, + ARM64_INS_ZIP1, + ARM64_INS_ZIP2, + + // alias insn + ARM64_INS_MNEG, + ARM64_INS_UMNEGL, + ARM64_INS_SMNEGL, + ARM64_INS_NOP, + ARM64_INS_YIELD, + ARM64_INS_WFE, + ARM64_INS_WFI, + ARM64_INS_SEV, + ARM64_INS_SEVL, + ARM64_INS_NGC, + ARM64_INS_SBFIZ, + ARM64_INS_UBFIZ, + ARM64_INS_SBFX, + ARM64_INS_UBFX, + ARM64_INS_BFI, + ARM64_INS_BFXIL, + ARM64_INS_CMN, + ARM64_INS_MVN, + ARM64_INS_TST, + ARM64_INS_CSET, + ARM64_INS_CINC, + ARM64_INS_CSETM, + ARM64_INS_CINV, + ARM64_INS_CNEG, + ARM64_INS_SXTB, + ARM64_INS_SXTH, + ARM64_INS_SXTW, + ARM64_INS_CMP, + ARM64_INS_UXTB, + ARM64_INS_UXTH, + ARM64_INS_UXTW, + ARM64_INS_IC, + ARM64_INS_DC, + ARM64_INS_AT, + ARM64_INS_TLBI, + + ARM64_INS_ENDING, // <-- mark the end of the list of insn +} arm64_insn; + +//> Group of ARM64 instructions +typedef enum arm64_insn_group { + ARM64_GRP_INVALID = 0, // = CS_GRP_INVALID + + //> Generic groups + // all jump instructions (conditional+direct+indirect jumps) + ARM64_GRP_JUMP, // = CS_GRP_JUMP + + //> Architecture-specific groups + ARM64_GRP_CRYPTO = 128, + ARM64_GRP_FPARMV8, + ARM64_GRP_NEON, + ARM64_GRP_CRC, + + ARM64_GRP_ENDING, // <-- mark the end of the list of groups +} arm64_insn_group; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/capstone.h b/include/capstone.h new file mode 100644 index 0000000..354e499 --- /dev/null +++ b/include/capstone.h @@ -0,0 +1,670 @@ +#ifndef CAPSTONE_ENGINE_H +#define CAPSTONE_ENGINE_H + +/* Capstone Disassembly Engine */ +/* By Nguyen Anh Quynh , 2013-2014 */ + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(_MSC_VER) || !defined(_KERNEL_MODE) +#include +#endif + +#include + +#if defined(CAPSTONE_HAS_OSXKERNEL) +#include +#else +#include +#include +#endif + +#include "platform.h" + +#ifdef _MSC_VER +#pragma warning(disable:4201) +#pragma warning(disable:4100) +#define CAPSTONE_API __cdecl +#ifdef CAPSTONE_SHARED +#define CAPSTONE_EXPORT __declspec(dllexport) +#else // defined(CAPSTONE_STATIC) +#define CAPSTONE_EXPORT +#endif +#else +#define CAPSTONE_API +#ifdef __GNUC__ +#define CAPSTONE_EXPORT __attribute__((visibility("default"))) +#else +#define CAPSTONE_EXPORT +#endif +#endif + +#ifdef __GNUC__ +#define CAPSTONE_DEPRECATED __attribute__((deprecated)) +#elif defined(_MSC_VER) +#define CAPSTONE_DEPRECATED __declspec(deprecated) +#else +#pragma message("WARNING: You need to implement CAPSTONE_DEPRECATED for this compiler") +#define CAPSTONE_DEPRECATED +#endif + +// Capstone API version +#define CS_API_MAJOR 3 +#define CS_API_MINOR 0 + +// Macro to create combined version which can be compared to +// result of cs_version() API. +#define CS_MAKE_VERSION(major, minor) ((major << 8) + minor) + +// Handle using with all API +typedef size_t csh; + +// Architecture type +typedef enum cs_arch { + CS_ARCH_ARM = 0, // ARM architecture (including Thumb, Thumb-2) + CS_ARCH_ARM64, // ARM-64, also called AArch64 + CS_ARCH_MIPS, // Mips architecture + CS_ARCH_X86, // X86 architecture (including x86 & x86-64) + CS_ARCH_PPC, // PowerPC architecture + CS_ARCH_SPARC, // Sparc architecture + CS_ARCH_SYSZ, // SystemZ architecture + CS_ARCH_XCORE, // XCore architecture + CS_ARCH_MAX, + CS_ARCH_ALL = 0xFFFF, // All architectures - for cs_support() +} cs_arch; + +// Support value to verify diet mode of the engine. +// If cs_support(CS_SUPPORT_DIET) return True, the engine was compiled +// in diet mode. +#define CS_SUPPORT_DIET (CS_ARCH_ALL + 1) + +// Support value to verify X86 reduce mode of the engine. +// If cs_support(CS_SUPPORT_X86_REDUCE) return True, the engine was compiled +// in X86 reduce mode. +#define CS_SUPPORT_X86_REDUCE (CS_ARCH_ALL + 2) + +// Mode type +typedef enum cs_mode { + CS_MODE_LITTLE_ENDIAN = 0, // little-endian mode (default mode) + CS_MODE_ARM = 0, // 32-bit ARM + CS_MODE_16 = 1 << 1, // 16-bit mode (X86) + CS_MODE_32 = 1 << 2, // 32-bit mode (X86) + CS_MODE_64 = 1 << 3, // 64-bit mode (X86, PPC) + CS_MODE_THUMB = 1 << 4, // ARM's Thumb mode, including Thumb-2 + CS_MODE_MCLASS = 1 << 5, // ARM's Cortex-M series + CS_MODE_V8 = 1 << 6, // ARMv8 A32 encodings for ARM + CS_MODE_MICRO = 1 << 4, // MicroMips mode (MIPS) + CS_MODE_MIPS3 = 1 << 5, // Mips III ISA + CS_MODE_MIPS32R6 = 1 << 6, // Mips32r6 ISA + CS_MODE_MIPSGP64 = 1 << 7, // General Purpose Registers are 64-bit wide (MIPS) + CS_MODE_V9 = 1 << 4, // SparcV9 mode (Sparc) + CS_MODE_BIG_ENDIAN = 1 << 31, // big-endian mode + CS_MODE_MIPS32 = CS_MODE_32, // Mips32 ISA (Mips) + CS_MODE_MIPS64 = CS_MODE_64, // Mips64 ISA (Mips) +} cs_mode; + +typedef void* (CAPSTONE_API *cs_malloc_t)(size_t size); +typedef void* (CAPSTONE_API *cs_calloc_t)(size_t nmemb, size_t size); +typedef void* (CAPSTONE_API *cs_realloc_t)(void *ptr, size_t size); +typedef void (CAPSTONE_API *cs_free_t)(void *ptr); +typedef int (CAPSTONE_API *cs_vsnprintf_t)(char *str, size_t size, const char *format, va_list ap); + + +// User-defined dynamic memory related functions: malloc/calloc/realloc/free/vsnprintf() +// By default, Capstone uses system's malloc(), calloc(), realloc(), free() & vsnprintf(). +typedef struct cs_opt_mem { + cs_malloc_t malloc; + cs_calloc_t calloc; + cs_realloc_t realloc; + cs_free_t free; + cs_vsnprintf_t vsnprintf; +} cs_opt_mem; + +// Runtime option for the disassembled engine +typedef enum cs_opt_type { + CS_OPT_INVALID = 0, // No option specified + CS_OPT_SYNTAX, // Assembly output syntax + CS_OPT_DETAIL, // Break down instruction structure into details + CS_OPT_MODE, // Change engine's mode at run-time + CS_OPT_MEM, // User-defined dynamic memory related functions + CS_OPT_SKIPDATA, // Skip data when disassembling. Then engine is in SKIPDATA mode. + CS_OPT_SKIPDATA_SETUP, // Setup user-defined function for SKIPDATA option +} cs_opt_type; + +// Runtime option value (associated with option type above) +typedef enum cs_opt_value { + CS_OPT_OFF = 0, // Turn OFF an option - default option of CS_OPT_DETAIL, CS_OPT_SKIPDATA. + CS_OPT_ON = 3, // Turn ON an option (CS_OPT_DETAIL, CS_OPT_SKIPDATA). + CS_OPT_SYNTAX_DEFAULT = 0, // Default asm syntax (CS_OPT_SYNTAX). + CS_OPT_SYNTAX_INTEL, // X86 Intel asm syntax - default on X86 (CS_OPT_SYNTAX). + CS_OPT_SYNTAX_ATT, // X86 ATT asm syntax (CS_OPT_SYNTAX). + CS_OPT_SYNTAX_NOREGNAME, // Prints register name with only number (CS_OPT_SYNTAX) +} cs_opt_value; + +//> Common instruction operand types - to be consistent across all architectures. +typedef enum cs_op_type { + CS_OP_INVALID = 0, // uninitialized/invalid operand. + CS_OP_REG, // Register operand. + CS_OP_IMM, // Immediate operand. + CS_OP_MEM, // Memory operand. + CS_OP_FP, // Floating-Point operand. +} cs_op_type; + +//> Common instruction groups - to be consistent across all architectures. +typedef enum cs_group_type { + CS_GRP_INVALID = 0, // uninitialized/invalid group. + CS_GRP_JUMP, // all jump instructions (conditional+direct+indirect jumps) + CS_GRP_CALL, // all call instructions + CS_GRP_RET, // all return instructions + CS_GRP_INT, // all interrupt instructions (int+syscall) + CS_GRP_IRET, // all interrupt return instructions +} cs_group_type; + +/* + User-defined callback function for SKIPDATA option. + See tests/test_skipdata.c for sample code demonstrating this API. + + @code: the input buffer containing code to be disassembled. + This is the same buffer passed to cs_disasm(). + @code_size: size (in bytes) of the above @code buffer. + @offset: the position of the currently-examining byte in the input + buffer @code mentioned above. + @user_data: user-data passed to cs_option() via @user_data field in + cs_opt_skipdata struct below. + + @return: return number of bytes to skip, or 0 to immediately stop disassembling. +*/ +typedef size_t (CAPSTONE_API *cs_skipdata_cb_t)(const uint8_t *code, size_t code_size, size_t offset, void *user_data); + +// User-customized setup for SKIPDATA option +typedef struct cs_opt_skipdata { + // Capstone considers data to skip as special "instructions". + // User can specify the string for this instruction's "mnemonic" here. + // By default (if @mnemonic is NULL), Capstone use ".byte". + const char *mnemonic; + + // User-defined callback function to be called when Capstone hits data. + // If the returned value from this callback is positive (>0), Capstone + // will skip exactly that number of bytes & continue. Otherwise, if + // the callback returns 0, Capstone stops disassembling and returns + // immediately from cs_disasm() + // NOTE: if this callback pointer is NULL, Capstone would skip a number + // of bytes depending on architectures, as following: + // Arm: 2 bytes (Thumb mode) or 4 bytes. + // Arm64: 4 bytes. + // Mips: 4 bytes. + // PowerPC: 4 bytes. + // Sparc: 4 bytes. + // SystemZ: 2 bytes. + // X86: 1 bytes. + // XCore: 2 bytes. + cs_skipdata_cb_t callback; // default value is NULL + + // User-defined data to be passed to @callback function pointer. + void *user_data; +} cs_opt_skipdata; + + +#include "arm.h" +#include "arm64.h" +#include "mips.h" +#include "ppc.h" +#include "sparc.h" +#include "systemz.h" +#include "x86.h" +#include "xcore.h" + +// NOTE: All information in cs_detail is only available when CS_OPT_DETAIL = CS_OPT_ON +typedef struct cs_detail { + uint8_t regs_read[12]; // list of implicit registers read by this insn + uint8_t regs_read_count; // number of implicit registers read by this insn + + uint8_t regs_write[20]; // list of implicit registers modified by this insn + uint8_t regs_write_count; // number of implicit registers modified by this insn + + uint8_t groups[8]; // list of group this instruction belong to + uint8_t groups_count; // number of groups this insn belongs to + + // Architecture-specific instruction info + union { + cs_x86 x86; // X86 architecture, including 16-bit, 32-bit & 64-bit mode + cs_arm64 arm64; // ARM64 architecture (aka AArch64) + cs_arm arm; // ARM architecture (including Thumb/Thumb2) + cs_mips mips; // MIPS architecture + cs_ppc ppc; // PowerPC architecture + cs_sparc sparc; // Sparc architecture + cs_sysz sysz; // SystemZ architecture + cs_xcore xcore; // XCore architecture + }; +} cs_detail; + +// Detail information of disassembled instruction +typedef struct cs_insn { + // Instruction ID (basically a numeric ID for the instruction mnemonic) + // Find the instruction id in the '[ARCH]_insn' enum in the header file + // of corresponding architecture, such as 'arm_insn' in arm.h for ARM, + // 'x86_insn' in x86.h for X86, etc... + // This information is available even when CS_OPT_DETAIL = CS_OPT_OFF + // NOTE: in Skipdata mode, "data" instruction has 0 for this id field. + unsigned int id; + + // Address (EIP) of this instruction + // This information is available even when CS_OPT_DETAIL = CS_OPT_OFF + uint64_t address; + + // Size of this instruction + // This information is available even when CS_OPT_DETAIL = CS_OPT_OFF + uint16_t size; + // Machine bytes of this instruction, with number of bytes indicated by @size above + // This information is available even when CS_OPT_DETAIL = CS_OPT_OFF + uint8_t bytes[16]; + + // Ascii text of instruction mnemonic + // This information is available even when CS_OPT_DETAIL = CS_OPT_OFF + char mnemonic[32]; + + // Ascii text of instruction operands + // This information is available even when CS_OPT_DETAIL = CS_OPT_OFF + char op_str[160]; + + // Pointer to cs_detail. + // NOTE: detail pointer is only valid when both requirements below are met: + // (1) CS_OP_DETAIL = CS_OPT_ON + // (2) Engine is not in Skipdata mode (CS_OP_SKIPDATA option set to CS_OPT_ON) + // + // NOTE 2: when in Skipdata mode, or when detail mode is OFF, even if this pointer + // is not NULL, its content is still irrelevant. + cs_detail *detail; +} cs_insn; + + +// Calculate the offset of a disassembled instruction in its buffer, given its position +// in its array of disassembled insn +// NOTE: this macro works with position (>=1), not index +#define CS_INSN_OFFSET(insns, post) (insns[post - 1].address - insns[0].address) + + +// All type of errors encountered by Capstone API. +// These are values returned by cs_errno() +typedef enum cs_err { + CS_ERR_OK = 0, // No error: everything was fine + CS_ERR_MEM, // Out-Of-Memory error: cs_open(), cs_disasm(), cs_disasm_iter() + CS_ERR_ARCH, // Unsupported architecture: cs_open() + CS_ERR_HANDLE, // Invalid handle: cs_op_count(), cs_op_index() + CS_ERR_CSH, // Invalid csh argument: cs_close(), cs_errno(), cs_option() + CS_ERR_MODE, // Invalid/unsupported mode: cs_open() + CS_ERR_OPTION, // Invalid/unsupported option: cs_option() + CS_ERR_DETAIL, // Information is unavailable because detail option is OFF + CS_ERR_MEMSETUP, // Dynamic memory management uninitialized (see CS_OPT_MEM) + CS_ERR_VERSION, // Unsupported version (bindings) + CS_ERR_DIET, // Access irrelevant data in "diet" engine + CS_ERR_SKIPDATA, // Access irrelevant data for "data" instruction in SKIPDATA mode + CS_ERR_X86_ATT, // X86 AT&T syntax is unsupported (opt-out at compile time) + CS_ERR_X86_INTEL, // X86 Intel syntax is unsupported (opt-out at compile time) +} cs_err; + +/* + Return combined API version & major and minor version numbers. + + @major: major number of API version + @minor: minor number of API version + + @return hexical number as (major << 8 | minor), which encodes both + major & minor versions. + NOTE: This returned value can be compared with version number made + with macro CS_MAKE_VERSION + + For example, second API version would return 1 in @major, and 1 in @minor + The return value would be 0x0101 + + NOTE: if you only care about returned value, but not major and minor values, + set both @major & @minor arguments to NULL. +*/ +CAPSTONE_EXPORT +unsigned int CAPSTONE_API cs_version(int *major, int *minor); + + +/* + This API can be used to either ask for archs supported by this library, + or check to see if the library was compile with 'diet' option (or called + in 'diet' mode). + + To check if a particular arch is supported by this library, set @query to + arch mode (CS_ARCH_* value). + To verify if this library supports all the archs, use CS_ARCH_ALL. + + To check if this library is in 'diet' mode, set @query to CS_SUPPORT_DIET. + + @return True if this library supports the given arch, or in 'diet' mode. +*/ +CAPSTONE_EXPORT +bool CAPSTONE_API cs_support(int query); + +/* + Initialize CS handle: this must be done before any usage of CS. + + @arch: architecture type (CS_ARCH_*) + @mode: hardware mode. This is combined of CS_MODE_* + @handle: pointer to handle, which will be updated at return time + + @return CS_ERR_OK on success, or other value on failure (refer to cs_err enum + for detailed error). +*/ +CAPSTONE_EXPORT +cs_err CAPSTONE_API cs_open(cs_arch arch, cs_mode mode, csh *handle); + +/* + Close CS handle: MUST do to release the handle when it is not used anymore. + NOTE: this must be only called when there is no longer usage of Capstone, + not even access to cs_insn array. The reason is the this API releases some + cached memory, thus access to any Capstone API after cs_close() might crash + your application. + + In fact,this API invalidate @handle by ZERO out its value (i.e *handle = 0). + + @handle: pointer to a handle returned by cs_open() + + @return CS_ERR_OK on success, or other value on failure (refer to cs_err enum + for detailed error). +*/ +CAPSTONE_EXPORT +cs_err CAPSTONE_API cs_close(csh *handle); + +/* + Set option for disassembling engine at runtime + + @handle: handle returned by cs_open() + @type: type of option to be set + @value: option value corresponding with @type + + @return: CS_ERR_OK on success, or other value on failure. + Refer to cs_err enum for detailed error. + + NOTE: in the case of CS_OPT_MEM, handle's value can be anything, + so that cs_option(handle, CS_OPT_MEM, value) can (i.e must) be called + even before cs_open() +*/ +CAPSTONE_EXPORT +cs_err CAPSTONE_API cs_option(csh handle, cs_opt_type type, size_t value); + +/* + Report the last error number when some API function fail. + Like glibc's errno, cs_errno might not retain its old value once accessed. + + @handle: handle returned by cs_open() + + @return: error code of cs_err enum type (CS_ERR_*, see above) +*/ +CAPSTONE_EXPORT +cs_err CAPSTONE_API cs_errno(csh handle); + + +/* + Return a string describing given error code. + + @code: error code (see CS_ERR_* above) + + @return: returns a pointer to a string that describes the error code + passed in the argument @code +*/ +CAPSTONE_EXPORT +const char * CAPSTONE_API cs_strerror(cs_err code); + +/* + Disassemble binary code, given the code buffer, size, address and number + of instructions to be decoded. + This API dynamically allocate memory to contain disassembled instruction. + Resulted instructions will be put into @*insn + + NOTE 1: this API will automatically determine memory needed to contain + output disassembled instructions in @insn. + + NOTE 2: caller must free the allocated memory itself to avoid memory leaking. + + NOTE 3: for system with scarce memory to be dynamically allocated such as + OS kernel or firmware, the API cs_disasm_iter() might be a better choice than + cs_disasm(). The reason is that with cs_disasm(), based on limited available + memory, we have to calculate in advance how many instructions to be disassembled, + which complicates things. This is especially troublesome for the case @count=0, + when cs_disasm() runs uncontrollably (until either end of input buffer, or + when it encounters an invalid instruction). + + @handle: handle returned by cs_open() + @code: buffer containing raw binary code to be disassembled. + @code_size: size of the above code buffer. + @address: address of the first instruction in given raw code buffer. + @insn: array of instructions filled in by this API. + NOTE: @insn will be allocated by this function, and should be freed + with cs_free() API. + @count: number of instructions to be disassembled, or 0 to get all of them + + @return: the number of successfully disassembled instructions, + or 0 if this function failed to disassemble the given code + + On failure, call cs_errno() for error code. +*/ +CAPSTONE_EXPORT +size_t CAPSTONE_API cs_disasm(csh handle, + const uint8_t *code, size_t code_size, + uint64_t address, + size_t count, + cs_insn **insn); + +/* + Deprecated function - to be retired in the next version! + Use cs_disasm() instead of cs_disasm_ex() +*/ +CAPSTONE_EXPORT +CAPSTONE_DEPRECATED +size_t CAPSTONE_API cs_disasm_ex(csh handle, + const uint8_t *code, size_t code_size, + uint64_t address, + size_t count, + cs_insn **insn); + +/* + Free memory allocated by cs_malloc() or cs_disasm() (argument @insn) + + @insn: pointer returned by @insn argument in cs_disasm() or cs_malloc() + @count: number of cs_insn structures returned by cs_disasm(), or 1 + to free memory allocated by cs_malloc(). +*/ +CAPSTONE_EXPORT +void CAPSTONE_API cs_free(cs_insn *insn, size_t count); + + +/* + Allocate memory for 1 instruction to be used by cs_disasm_iter(). + + @handle: handle returned by cs_open() + + NOTE: when no longer in use, you can reclaim the memory allocated for + this instruction with cs_free(insn, 1) +*/ +CAPSTONE_EXPORT +cs_insn * CAPSTONE_API cs_malloc(csh handle); + +/* + Fast API to disassemble binary code, given the code buffer, size, address + and number of instructions to be decoded. + This API put the resulted instruction into a given cache in @insn. + See tests/test_iter.c for sample code demonstrating this API. + + NOTE 1: this API will update @code, @size & @address to point to the next + instruction in the input buffer. Therefore, it is convenient to use + cs_disasm_iter() inside a loop to quickly iterate all the instructions. + While decoding one instruction at a time can also be achieved with + cs_disasm(count=1), some benchmarks shown that cs_disasm_iter() can be 30% + faster on random input. + + NOTE 2: the cache in @insn can be created with cs_malloc() API. + + NOTE 3: for system with scarce memory to be dynamically allocated such as + OS kernel or firmware, this API is recommended over cs_disasm(), which + allocates memory based on the number of instructions to be disassembled. + The reason is that with cs_disasm(), based on limited available memory, + we have to calculate in advance how many instructions to be disassembled, + which complicates things. This is especially troublesome for the case + @count=0, when cs_disasm() runs uncontrollably (until either end of input + buffer, or when it encounters an invalid instruction). + + @handle: handle returned by cs_open() + @code: buffer containing raw binary code to be disassembled + @size: size of above code + @address: address of the first insn in given raw code buffer + @insn: pointer to instruction to be filled in by this API. + + @return: true if this API successfully decode 1 instruction, + or false otherwise. + + On failure, call cs_errno() for error code. +*/ +CAPSTONE_EXPORT +bool CAPSTONE_API cs_disasm_iter(csh handle, + const uint8_t **code, size_t *size, + uint64_t *address, cs_insn *insn); + +/* + Return friendly name of register in a string. + Find the instruction id from header file of corresponding architecture (arm.h for ARM, + x86.h for X86, ...) + + WARN: when in 'diet' mode, this API is irrelevant because engine does not + store register name. + + @handle: handle returned by cs_open() + @reg_id: register id + + @return: string name of the register, or NULL if @reg_id is invalid. +*/ +CAPSTONE_EXPORT +const char * CAPSTONE_API cs_reg_name(csh handle, unsigned int reg_id); + +/* + Return friendly name of an instruction in a string. + Find the instruction id from header file of corresponding architecture (arm.h for ARM, x86.h for X86, ...) + + WARN: when in 'diet' mode, this API is irrelevant because the engine does not + store instruction name. + + @handle: handle returned by cs_open() + @insn_id: instruction id + + @return: string name of the instruction, or NULL if @insn_id is invalid. +*/ +CAPSTONE_EXPORT +const char * CAPSTONE_API cs_insn_name(csh handle, unsigned int insn_id); + +/* + Return friendly name of a group id (that an instruction can belong to) + Find the group id from header file of corresponding architecture (arm.h for ARM, x86.h for X86, ...) + + WARN: when in 'diet' mode, this API is irrelevant because the engine does not + store group name. + + @handle: handle returned by cs_open() + @group_id: group id + + @return: string name of the group, or NULL if @group_id is invalid. +*/ +CAPSTONE_EXPORT +const char * CAPSTONE_API cs_group_name(csh handle, unsigned int group_id); + +/* + Check if a disassembled instruction belong to a particular group. + Find the group id from header file of corresponding architecture (arm.h for ARM, x86.h for X86, ...) + Internally, this simply verifies if @group_id matches any member of insn->groups array. + + NOTE: this API is only valid when detail option is ON (which is OFF by default). + + WARN: when in 'diet' mode, this API is irrelevant because the engine does not + update @groups array. + + @handle: handle returned by cs_open() + @insn: disassembled instruction structure received from cs_disasm() or cs_disasm_iter() + @group_id: group that you want to check if this instruction belong to. + + @return: true if this instruction indeed belongs to aboved group, or false otherwise. +*/ +CAPSTONE_EXPORT +bool CAPSTONE_API cs_insn_group(csh handle, const cs_insn *insn, unsigned int group_id); + +/* + Check if a disassembled instruction IMPLICITLY used a particular register. + Find the register id from header file of corresponding architecture (arm.h for ARM, x86.h for X86, ...) + Internally, this simply verifies if @reg_id matches any member of insn->regs_read array. + + NOTE: this API is only valid when detail option is ON (which is OFF by default) + + WARN: when in 'diet' mode, this API is irrelevant because the engine does not + update @regs_read array. + + @insn: disassembled instruction structure received from cs_disasm() or cs_disasm_iter() + @reg_id: register that you want to check if this instruction used it. + + @return: true if this instruction indeed implicitly used aboved register, or false otherwise. +*/ +CAPSTONE_EXPORT +bool CAPSTONE_API cs_reg_read(csh handle, const cs_insn *insn, unsigned int reg_id); + +/* + Check if a disassembled instruction IMPLICITLY modified a particular register. + Find the register id from header file of corresponding architecture (arm.h for ARM, x86.h for X86, ...) + Internally, this simply verifies if @reg_id matches any member of insn->regs_write array. + + NOTE: this API is only valid when detail option is ON (which is OFF by default) + + WARN: when in 'diet' mode, this API is irrelevant because the engine does not + update @regs_write array. + + @insn: disassembled instruction structure received from cs_disasm() or cs_disasm_iter() + @reg_id: register that you want to check if this instruction modified it. + + @return: true if this instruction indeed implicitly modified aboved register, or false otherwise. +*/ +CAPSTONE_EXPORT +bool CAPSTONE_API cs_reg_write(csh handle, const cs_insn *insn, unsigned int reg_id); + +/* + Count the number of operands of a given type. + Find the operand type in header file of corresponding architecture (arm.h for ARM, x86.h for X86, ...) + + NOTE: this API is only valid when detail option is ON (which is OFF by default) + + @handle: handle returned by cs_open() + @insn: disassembled instruction structure received from cs_disasm() or cs_disasm_iter() + @op_type: Operand type to be found. + + @return: number of operands of given type @op_type in instruction @insn, + or -1 on failure. +*/ +CAPSTONE_EXPORT +int CAPSTONE_API cs_op_count(csh handle, const cs_insn *insn, unsigned int op_type); + +/* + Retrieve the position of operand of given type in .operands[] array. + Later, the operand can be accessed using the returned position. + Find the operand type in header file of corresponding architecture (arm.h for ARM, x86.h for X86, ...) + + NOTE: this API is only valid when detail option is ON (which is OFF by default) + + @handle: handle returned by cs_open() + @insn: disassembled instruction structure received from cs_disasm() or cs_disasm_iter() + @op_type: Operand type to be found. + @position: position of the operand to be found. This must be in the range + [1, cs_op_count(handle, insn, op_type)] + + @return: index of operand of given type @op_type in .operands[] array + in instruction @insn, or -1 on failure. +*/ +CAPSTONE_EXPORT +int CAPSTONE_API cs_op_index(csh handle, const cs_insn *insn, unsigned int op_type, + unsigned int position); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/mips.h b/include/mips.h new file mode 100644 index 0000000..d238fda --- /dev/null +++ b/include/mips.h @@ -0,0 +1,906 @@ +#ifndef CAPSTONE_MIPS_H +#define CAPSTONE_MIPS_H + +/* Capstone Disassembly Engine */ +/* By Nguyen Anh Quynh , 2013-2014 */ + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(_MSC_VER) || !defined(_KERNEL_MODE) +#include +#endif + +#include "platform.h" + +// GCC MIPS toolchain has a default macro called "mips" which breaks +// compilation +#undef mips + +#ifdef _MSC_VER +#pragma warning(disable:4201) +#endif + +//> Operand type for instruction's operands +typedef enum mips_op_type { + MIPS_OP_INVALID = 0, // = CS_OP_INVALID (Uninitialized). + MIPS_OP_REG, // = CS_OP_REG (Register operand). + MIPS_OP_IMM, // = CS_OP_IMM (Immediate operand). + MIPS_OP_MEM, // = CS_OP_MEM (Memory operand). +} mips_op_type; + +// Instruction's operand referring to memory +// This is associated with MIPS_OP_MEM operand type above +typedef struct mips_op_mem { + unsigned int base; // base register + int64_t disp; // displacement/offset value +} mips_op_mem; + +// Instruction operand +typedef struct cs_mips_op { + mips_op_type type; // operand type + union { + unsigned int reg; // register value for REG operand + int64_t imm; // immediate value for IMM operand + mips_op_mem mem; // base/index/scale/disp value for MEM operand + }; +} cs_mips_op; + +// Instruction structure +typedef struct cs_mips { + // Number of operands of this instruction, + // or 0 when instruction has no operand. + uint8_t op_count; + cs_mips_op operands[8]; // operands for this instruction. +} cs_mips; + +//> MIPS registers +typedef enum mips_reg { + MIPS_REG_INVALID = 0, + //> General purpose registers + MIPS_REG_0, + MIPS_REG_1, + MIPS_REG_2, + MIPS_REG_3, + MIPS_REG_4, + MIPS_REG_5, + MIPS_REG_6, + MIPS_REG_7, + MIPS_REG_8, + MIPS_REG_9, + MIPS_REG_10, + MIPS_REG_11, + MIPS_REG_12, + MIPS_REG_13, + MIPS_REG_14, + MIPS_REG_15, + MIPS_REG_16, + MIPS_REG_17, + MIPS_REG_18, + MIPS_REG_19, + MIPS_REG_20, + MIPS_REG_21, + MIPS_REG_22, + MIPS_REG_23, + MIPS_REG_24, + MIPS_REG_25, + MIPS_REG_26, + MIPS_REG_27, + MIPS_REG_28, + MIPS_REG_29, + MIPS_REG_30, + MIPS_REG_31, + + //> DSP registers + MIPS_REG_DSPCCOND, + MIPS_REG_DSPCARRY, + MIPS_REG_DSPEFI, + MIPS_REG_DSPOUTFLAG, + MIPS_REG_DSPOUTFLAG16_19, + MIPS_REG_DSPOUTFLAG20, + MIPS_REG_DSPOUTFLAG21, + MIPS_REG_DSPOUTFLAG22, + MIPS_REG_DSPOUTFLAG23, + MIPS_REG_DSPPOS, + MIPS_REG_DSPSCOUNT, + + //> ACC registers + MIPS_REG_AC0, + MIPS_REG_AC1, + MIPS_REG_AC2, + MIPS_REG_AC3, + + //> COP registers + MIPS_REG_CC0, + MIPS_REG_CC1, + MIPS_REG_CC2, + MIPS_REG_CC3, + MIPS_REG_CC4, + MIPS_REG_CC5, + MIPS_REG_CC6, + MIPS_REG_CC7, + + //> FPU registers + MIPS_REG_F0, + MIPS_REG_F1, + MIPS_REG_F2, + MIPS_REG_F3, + MIPS_REG_F4, + MIPS_REG_F5, + MIPS_REG_F6, + MIPS_REG_F7, + MIPS_REG_F8, + MIPS_REG_F9, + MIPS_REG_F10, + MIPS_REG_F11, + MIPS_REG_F12, + MIPS_REG_F13, + MIPS_REG_F14, + MIPS_REG_F15, + MIPS_REG_F16, + MIPS_REG_F17, + MIPS_REG_F18, + MIPS_REG_F19, + MIPS_REG_F20, + MIPS_REG_F21, + MIPS_REG_F22, + MIPS_REG_F23, + MIPS_REG_F24, + MIPS_REG_F25, + MIPS_REG_F26, + MIPS_REG_F27, + MIPS_REG_F28, + MIPS_REG_F29, + MIPS_REG_F30, + MIPS_REG_F31, + + MIPS_REG_FCC0, + MIPS_REG_FCC1, + MIPS_REG_FCC2, + MIPS_REG_FCC3, + MIPS_REG_FCC4, + MIPS_REG_FCC5, + MIPS_REG_FCC6, + MIPS_REG_FCC7, + + //> AFPR128 + MIPS_REG_W0, + MIPS_REG_W1, + MIPS_REG_W2, + MIPS_REG_W3, + MIPS_REG_W4, + MIPS_REG_W5, + MIPS_REG_W6, + MIPS_REG_W7, + MIPS_REG_W8, + MIPS_REG_W9, + MIPS_REG_W10, + MIPS_REG_W11, + MIPS_REG_W12, + MIPS_REG_W13, + MIPS_REG_W14, + MIPS_REG_W15, + MIPS_REG_W16, + MIPS_REG_W17, + MIPS_REG_W18, + MIPS_REG_W19, + MIPS_REG_W20, + MIPS_REG_W21, + MIPS_REG_W22, + MIPS_REG_W23, + MIPS_REG_W24, + MIPS_REG_W25, + MIPS_REG_W26, + MIPS_REG_W27, + MIPS_REG_W28, + MIPS_REG_W29, + MIPS_REG_W30, + MIPS_REG_W31, + + MIPS_REG_HI, + MIPS_REG_LO, + + MIPS_REG_P0, + MIPS_REG_P1, + MIPS_REG_P2, + + MIPS_REG_MPL0, + MIPS_REG_MPL1, + MIPS_REG_MPL2, + + MIPS_REG_ENDING, // <-- mark the end of the list or registers + + // alias registers + MIPS_REG_ZERO = MIPS_REG_0, + MIPS_REG_AT = MIPS_REG_1, + MIPS_REG_V0 = MIPS_REG_2, + MIPS_REG_V1 = MIPS_REG_3, + MIPS_REG_A0 = MIPS_REG_4, + MIPS_REG_A1 = MIPS_REG_5, + MIPS_REG_A2 = MIPS_REG_6, + MIPS_REG_A3 = MIPS_REG_7, + MIPS_REG_T0 = MIPS_REG_8, + MIPS_REG_T1 = MIPS_REG_9, + MIPS_REG_T2 = MIPS_REG_10, + MIPS_REG_T3 = MIPS_REG_11, + MIPS_REG_T4 = MIPS_REG_12, + MIPS_REG_T5 = MIPS_REG_13, + MIPS_REG_T6 = MIPS_REG_14, + MIPS_REG_T7 = MIPS_REG_15, + MIPS_REG_S0 = MIPS_REG_16, + MIPS_REG_S1 = MIPS_REG_17, + MIPS_REG_S2 = MIPS_REG_18, + MIPS_REG_S3 = MIPS_REG_19, + MIPS_REG_S4 = MIPS_REG_20, + MIPS_REG_S5 = MIPS_REG_21, + MIPS_REG_S6 = MIPS_REG_22, + MIPS_REG_S7 = MIPS_REG_23, + MIPS_REG_T8 = MIPS_REG_24, + MIPS_REG_T9 = MIPS_REG_25, + MIPS_REG_K0 = MIPS_REG_26, + MIPS_REG_K1 = MIPS_REG_27, + MIPS_REG_GP = MIPS_REG_28, + MIPS_REG_SP = MIPS_REG_29, + MIPS_REG_FP = MIPS_REG_30, MIPS_REG_S8 = MIPS_REG_30, + MIPS_REG_RA = MIPS_REG_31, + + MIPS_REG_HI0 = MIPS_REG_AC0, + MIPS_REG_HI1 = MIPS_REG_AC1, + MIPS_REG_HI2 = MIPS_REG_AC2, + MIPS_REG_HI3 = MIPS_REG_AC3, + + MIPS_REG_LO0 = MIPS_REG_HI0, + MIPS_REG_LO1 = MIPS_REG_HI1, + MIPS_REG_LO2 = MIPS_REG_HI2, + MIPS_REG_LO3 = MIPS_REG_HI3, +} mips_reg; + +//> MIPS instruction +typedef enum mips_insn { + MIPS_INS_INVALID = 0, + + MIPS_INS_ABSQ_S, + MIPS_INS_ADD, + MIPS_INS_ADDIUPC, + MIPS_INS_ADDQH, + MIPS_INS_ADDQH_R, + MIPS_INS_ADDQ, + MIPS_INS_ADDQ_S, + MIPS_INS_ADDSC, + MIPS_INS_ADDS_A, + MIPS_INS_ADDS_S, + MIPS_INS_ADDS_U, + MIPS_INS_ADDUH, + MIPS_INS_ADDUH_R, + MIPS_INS_ADDU, + MIPS_INS_ADDU_S, + MIPS_INS_ADDVI, + MIPS_INS_ADDV, + MIPS_INS_ADDWC, + MIPS_INS_ADD_A, + MIPS_INS_ADDI, + MIPS_INS_ADDIU, + MIPS_INS_ALIGN, + MIPS_INS_ALUIPC, + MIPS_INS_AND, + MIPS_INS_ANDI, + MIPS_INS_APPEND, + MIPS_INS_ASUB_S, + MIPS_INS_ASUB_U, + MIPS_INS_AUI, + MIPS_INS_AUIPC, + MIPS_INS_AVER_S, + MIPS_INS_AVER_U, + MIPS_INS_AVE_S, + MIPS_INS_AVE_U, + MIPS_INS_BADDU, + MIPS_INS_BAL, + MIPS_INS_BALC, + MIPS_INS_BALIGN, + MIPS_INS_BC, + MIPS_INS_BC0F, + MIPS_INS_BC0FL, + MIPS_INS_BC0T, + MIPS_INS_BC0TL, + MIPS_INS_BC1EQZ, + MIPS_INS_BC1F, + MIPS_INS_BC1FL, + MIPS_INS_BC1NEZ, + MIPS_INS_BC1T, + MIPS_INS_BC1TL, + MIPS_INS_BC2EQZ, + MIPS_INS_BC2F, + MIPS_INS_BC2FL, + MIPS_INS_BC2NEZ, + MIPS_INS_BC2T, + MIPS_INS_BC2TL, + MIPS_INS_BC3F, + MIPS_INS_BC3FL, + MIPS_INS_BC3T, + MIPS_INS_BC3TL, + MIPS_INS_BCLRI, + MIPS_INS_BCLR, + MIPS_INS_BEQ, + MIPS_INS_BEQC, + MIPS_INS_BEQL, + MIPS_INS_BEQZALC, + MIPS_INS_BEQZC, + MIPS_INS_BGEC, + MIPS_INS_BGEUC, + MIPS_INS_BGEZ, + MIPS_INS_BGEZAL, + MIPS_INS_BGEZALC, + MIPS_INS_BGEZALL, + MIPS_INS_BGEZALS, + MIPS_INS_BGEZC, + MIPS_INS_BGEZL, + MIPS_INS_BGTZ, + MIPS_INS_BGTZALC, + MIPS_INS_BGTZC, + MIPS_INS_BGTZL, + MIPS_INS_BINSLI, + MIPS_INS_BINSL, + MIPS_INS_BINSRI, + MIPS_INS_BINSR, + MIPS_INS_BITREV, + MIPS_INS_BITSWAP, + MIPS_INS_BLEZ, + MIPS_INS_BLEZALC, + MIPS_INS_BLEZC, + MIPS_INS_BLEZL, + MIPS_INS_BLTC, + MIPS_INS_BLTUC, + MIPS_INS_BLTZ, + MIPS_INS_BLTZAL, + MIPS_INS_BLTZALC, + MIPS_INS_BLTZALL, + MIPS_INS_BLTZALS, + MIPS_INS_BLTZC, + MIPS_INS_BLTZL, + MIPS_INS_BMNZI, + MIPS_INS_BMNZ, + MIPS_INS_BMZI, + MIPS_INS_BMZ, + MIPS_INS_BNE, + MIPS_INS_BNEC, + MIPS_INS_BNEGI, + MIPS_INS_BNEG, + MIPS_INS_BNEL, + MIPS_INS_BNEZALC, + MIPS_INS_BNEZC, + MIPS_INS_BNVC, + MIPS_INS_BNZ, + MIPS_INS_BOVC, + MIPS_INS_BPOSGE32, + MIPS_INS_BREAK, + MIPS_INS_BSELI, + MIPS_INS_BSEL, + MIPS_INS_BSETI, + MIPS_INS_BSET, + MIPS_INS_BZ, + MIPS_INS_BEQZ, + MIPS_INS_B, + MIPS_INS_BNEZ, + MIPS_INS_BTEQZ, + MIPS_INS_BTNEZ, + MIPS_INS_CACHE, + MIPS_INS_CEIL, + MIPS_INS_CEQI, + MIPS_INS_CEQ, + MIPS_INS_CFC1, + MIPS_INS_CFCMSA, + MIPS_INS_CINS, + MIPS_INS_CINS32, + MIPS_INS_CLASS, + MIPS_INS_CLEI_S, + MIPS_INS_CLEI_U, + MIPS_INS_CLE_S, + MIPS_INS_CLE_U, + MIPS_INS_CLO, + MIPS_INS_CLTI_S, + MIPS_INS_CLTI_U, + MIPS_INS_CLT_S, + MIPS_INS_CLT_U, + MIPS_INS_CLZ, + MIPS_INS_CMPGDU, + MIPS_INS_CMPGU, + MIPS_INS_CMPU, + MIPS_INS_CMP, + MIPS_INS_COPY_S, + MIPS_INS_COPY_U, + MIPS_INS_CTC1, + MIPS_INS_CTCMSA, + MIPS_INS_CVT, + MIPS_INS_C, + MIPS_INS_CMPI, + MIPS_INS_DADD, + MIPS_INS_DADDI, + MIPS_INS_DADDIU, + MIPS_INS_DADDU, + MIPS_INS_DAHI, + MIPS_INS_DALIGN, + MIPS_INS_DATI, + MIPS_INS_DAUI, + MIPS_INS_DBITSWAP, + MIPS_INS_DCLO, + MIPS_INS_DCLZ, + MIPS_INS_DDIV, + MIPS_INS_DDIVU, + MIPS_INS_DERET, + MIPS_INS_DEXT, + MIPS_INS_DEXTM, + MIPS_INS_DEXTU, + MIPS_INS_DI, + MIPS_INS_DINS, + MIPS_INS_DINSM, + MIPS_INS_DINSU, + MIPS_INS_DIV, + MIPS_INS_DIVU, + MIPS_INS_DIV_S, + MIPS_INS_DIV_U, + MIPS_INS_DLSA, + MIPS_INS_DMFC0, + MIPS_INS_DMFC1, + MIPS_INS_DMFC2, + MIPS_INS_DMOD, + MIPS_INS_DMODU, + MIPS_INS_DMTC0, + MIPS_INS_DMTC1, + MIPS_INS_DMTC2, + MIPS_INS_DMUH, + MIPS_INS_DMUHU, + MIPS_INS_DMUL, + MIPS_INS_DMULT, + MIPS_INS_DMULTU, + MIPS_INS_DMULU, + MIPS_INS_DOTP_S, + MIPS_INS_DOTP_U, + MIPS_INS_DPADD_S, + MIPS_INS_DPADD_U, + MIPS_INS_DPAQX_SA, + MIPS_INS_DPAQX_S, + MIPS_INS_DPAQ_SA, + MIPS_INS_DPAQ_S, + MIPS_INS_DPAU, + MIPS_INS_DPAX, + MIPS_INS_DPA, + MIPS_INS_DPOP, + MIPS_INS_DPSQX_SA, + MIPS_INS_DPSQX_S, + MIPS_INS_DPSQ_SA, + MIPS_INS_DPSQ_S, + MIPS_INS_DPSUB_S, + MIPS_INS_DPSUB_U, + MIPS_INS_DPSU, + MIPS_INS_DPSX, + MIPS_INS_DPS, + MIPS_INS_DROTR, + MIPS_INS_DROTR32, + MIPS_INS_DROTRV, + MIPS_INS_DSBH, + MIPS_INS_DSHD, + MIPS_INS_DSLL, + MIPS_INS_DSLL32, + MIPS_INS_DSLLV, + MIPS_INS_DSRA, + MIPS_INS_DSRA32, + MIPS_INS_DSRAV, + MIPS_INS_DSRL, + MIPS_INS_DSRL32, + MIPS_INS_DSRLV, + MIPS_INS_DSUB, + MIPS_INS_DSUBU, + MIPS_INS_EHB, + MIPS_INS_EI, + MIPS_INS_ERET, + MIPS_INS_EXT, + MIPS_INS_EXTP, + MIPS_INS_EXTPDP, + MIPS_INS_EXTPDPV, + MIPS_INS_EXTPV, + MIPS_INS_EXTRV_RS, + MIPS_INS_EXTRV_R, + MIPS_INS_EXTRV_S, + MIPS_INS_EXTRV, + MIPS_INS_EXTR_RS, + MIPS_INS_EXTR_R, + MIPS_INS_EXTR_S, + MIPS_INS_EXTR, + MIPS_INS_EXTS, + MIPS_INS_EXTS32, + MIPS_INS_ABS, + MIPS_INS_FADD, + MIPS_INS_FCAF, + MIPS_INS_FCEQ, + MIPS_INS_FCLASS, + MIPS_INS_FCLE, + MIPS_INS_FCLT, + MIPS_INS_FCNE, + MIPS_INS_FCOR, + MIPS_INS_FCUEQ, + MIPS_INS_FCULE, + MIPS_INS_FCULT, + MIPS_INS_FCUNE, + MIPS_INS_FCUN, + MIPS_INS_FDIV, + MIPS_INS_FEXDO, + MIPS_INS_FEXP2, + MIPS_INS_FEXUPL, + MIPS_INS_FEXUPR, + MIPS_INS_FFINT_S, + MIPS_INS_FFINT_U, + MIPS_INS_FFQL, + MIPS_INS_FFQR, + MIPS_INS_FILL, + MIPS_INS_FLOG2, + MIPS_INS_FLOOR, + MIPS_INS_FMADD, + MIPS_INS_FMAX_A, + MIPS_INS_FMAX, + MIPS_INS_FMIN_A, + MIPS_INS_FMIN, + MIPS_INS_MOV, + MIPS_INS_FMSUB, + MIPS_INS_FMUL, + MIPS_INS_MUL, + MIPS_INS_NEG, + MIPS_INS_FRCP, + MIPS_INS_FRINT, + MIPS_INS_FRSQRT, + MIPS_INS_FSAF, + MIPS_INS_FSEQ, + MIPS_INS_FSLE, + MIPS_INS_FSLT, + MIPS_INS_FSNE, + MIPS_INS_FSOR, + MIPS_INS_FSQRT, + MIPS_INS_SQRT, + MIPS_INS_FSUB, + MIPS_INS_SUB, + MIPS_INS_FSUEQ, + MIPS_INS_FSULE, + MIPS_INS_FSULT, + MIPS_INS_FSUNE, + MIPS_INS_FSUN, + MIPS_INS_FTINT_S, + MIPS_INS_FTINT_U, + MIPS_INS_FTQ, + MIPS_INS_FTRUNC_S, + MIPS_INS_FTRUNC_U, + MIPS_INS_HADD_S, + MIPS_INS_HADD_U, + MIPS_INS_HSUB_S, + MIPS_INS_HSUB_U, + MIPS_INS_ILVEV, + MIPS_INS_ILVL, + MIPS_INS_ILVOD, + MIPS_INS_ILVR, + MIPS_INS_INS, + MIPS_INS_INSERT, + MIPS_INS_INSV, + MIPS_INS_INSVE, + MIPS_INS_J, + MIPS_INS_JAL, + MIPS_INS_JALR, + MIPS_INS_JALRS, + MIPS_INS_JALS, + MIPS_INS_JALX, + MIPS_INS_JIALC, + MIPS_INS_JIC, + MIPS_INS_JR, + MIPS_INS_JRADDIUSP, + MIPS_INS_JRC, + MIPS_INS_JALRC, + MIPS_INS_LB, + MIPS_INS_LBUX, + MIPS_INS_LBU, + MIPS_INS_LD, + MIPS_INS_LDC1, + MIPS_INS_LDC2, + MIPS_INS_LDC3, + MIPS_INS_LDI, + MIPS_INS_LDL, + MIPS_INS_LDPC, + MIPS_INS_LDR, + MIPS_INS_LDXC1, + MIPS_INS_LH, + MIPS_INS_LHX, + MIPS_INS_LHU, + MIPS_INS_LL, + MIPS_INS_LLD, + MIPS_INS_LSA, + MIPS_INS_LUXC1, + MIPS_INS_LUI, + MIPS_INS_LW, + MIPS_INS_LWC1, + MIPS_INS_LWC2, + MIPS_INS_LWC3, + MIPS_INS_LWL, + MIPS_INS_LWPC, + MIPS_INS_LWR, + MIPS_INS_LWUPC, + MIPS_INS_LWU, + MIPS_INS_LWX, + MIPS_INS_LWXC1, + MIPS_INS_LI, + MIPS_INS_MADD, + MIPS_INS_MADDF, + MIPS_INS_MADDR_Q, + MIPS_INS_MADDU, + MIPS_INS_MADDV, + MIPS_INS_MADD_Q, + MIPS_INS_MAQ_SA, + MIPS_INS_MAQ_S, + MIPS_INS_MAXA, + MIPS_INS_MAXI_S, + MIPS_INS_MAXI_U, + MIPS_INS_MAX_A, + MIPS_INS_MAX, + MIPS_INS_MAX_S, + MIPS_INS_MAX_U, + MIPS_INS_MFC0, + MIPS_INS_MFC1, + MIPS_INS_MFC2, + MIPS_INS_MFHC1, + MIPS_INS_MFHI, + MIPS_INS_MFLO, + MIPS_INS_MINA, + MIPS_INS_MINI_S, + MIPS_INS_MINI_U, + MIPS_INS_MIN_A, + MIPS_INS_MIN, + MIPS_INS_MIN_S, + MIPS_INS_MIN_U, + MIPS_INS_MOD, + MIPS_INS_MODSUB, + MIPS_INS_MODU, + MIPS_INS_MOD_S, + MIPS_INS_MOD_U, + MIPS_INS_MOVE, + MIPS_INS_MOVF, + MIPS_INS_MOVN, + MIPS_INS_MOVT, + MIPS_INS_MOVZ, + MIPS_INS_MSUB, + MIPS_INS_MSUBF, + MIPS_INS_MSUBR_Q, + MIPS_INS_MSUBU, + MIPS_INS_MSUBV, + MIPS_INS_MSUB_Q, + MIPS_INS_MTC0, + MIPS_INS_MTC1, + MIPS_INS_MTC2, + MIPS_INS_MTHC1, + MIPS_INS_MTHI, + MIPS_INS_MTHLIP, + MIPS_INS_MTLO, + MIPS_INS_MTM0, + MIPS_INS_MTM1, + MIPS_INS_MTM2, + MIPS_INS_MTP0, + MIPS_INS_MTP1, + MIPS_INS_MTP2, + MIPS_INS_MUH, + MIPS_INS_MUHU, + MIPS_INS_MULEQ_S, + MIPS_INS_MULEU_S, + MIPS_INS_MULQ_RS, + MIPS_INS_MULQ_S, + MIPS_INS_MULR_Q, + MIPS_INS_MULSAQ_S, + MIPS_INS_MULSA, + MIPS_INS_MULT, + MIPS_INS_MULTU, + MIPS_INS_MULU, + MIPS_INS_MULV, + MIPS_INS_MUL_Q, + MIPS_INS_MUL_S, + MIPS_INS_NLOC, + MIPS_INS_NLZC, + MIPS_INS_NMADD, + MIPS_INS_NMSUB, + MIPS_INS_NOR, + MIPS_INS_NORI, + MIPS_INS_NOT, + MIPS_INS_OR, + MIPS_INS_ORI, + MIPS_INS_PACKRL, + MIPS_INS_PAUSE, + MIPS_INS_PCKEV, + MIPS_INS_PCKOD, + MIPS_INS_PCNT, + MIPS_INS_PICK, + MIPS_INS_POP, + MIPS_INS_PRECEQU, + MIPS_INS_PRECEQ, + MIPS_INS_PRECEU, + MIPS_INS_PRECRQU_S, + MIPS_INS_PRECRQ, + MIPS_INS_PRECRQ_RS, + MIPS_INS_PRECR, + MIPS_INS_PRECR_SRA, + MIPS_INS_PRECR_SRA_R, + MIPS_INS_PREF, + MIPS_INS_PREPEND, + MIPS_INS_RADDU, + MIPS_INS_RDDSP, + MIPS_INS_RDHWR, + MIPS_INS_REPLV, + MIPS_INS_REPL, + MIPS_INS_RINT, + MIPS_INS_ROTR, + MIPS_INS_ROTRV, + MIPS_INS_ROUND, + MIPS_INS_SAT_S, + MIPS_INS_SAT_U, + MIPS_INS_SB, + MIPS_INS_SC, + MIPS_INS_SCD, + MIPS_INS_SD, + MIPS_INS_SDBBP, + MIPS_INS_SDC1, + MIPS_INS_SDC2, + MIPS_INS_SDC3, + MIPS_INS_SDL, + MIPS_INS_SDR, + MIPS_INS_SDXC1, + MIPS_INS_SEB, + MIPS_INS_SEH, + MIPS_INS_SELEQZ, + MIPS_INS_SELNEZ, + MIPS_INS_SEL, + MIPS_INS_SEQ, + MIPS_INS_SEQI, + MIPS_INS_SH, + MIPS_INS_SHF, + MIPS_INS_SHILO, + MIPS_INS_SHILOV, + MIPS_INS_SHLLV, + MIPS_INS_SHLLV_S, + MIPS_INS_SHLL, + MIPS_INS_SHLL_S, + MIPS_INS_SHRAV, + MIPS_INS_SHRAV_R, + MIPS_INS_SHRA, + MIPS_INS_SHRA_R, + MIPS_INS_SHRLV, + MIPS_INS_SHRL, + MIPS_INS_SLDI, + MIPS_INS_SLD, + MIPS_INS_SLL, + MIPS_INS_SLLI, + MIPS_INS_SLLV, + MIPS_INS_SLT, + MIPS_INS_SLTI, + MIPS_INS_SLTIU, + MIPS_INS_SLTU, + MIPS_INS_SNE, + MIPS_INS_SNEI, + MIPS_INS_SPLATI, + MIPS_INS_SPLAT, + MIPS_INS_SRA, + MIPS_INS_SRAI, + MIPS_INS_SRARI, + MIPS_INS_SRAR, + MIPS_INS_SRAV, + MIPS_INS_SRL, + MIPS_INS_SRLI, + MIPS_INS_SRLRI, + MIPS_INS_SRLR, + MIPS_INS_SRLV, + MIPS_INS_SSNOP, + MIPS_INS_ST, + MIPS_INS_SUBQH, + MIPS_INS_SUBQH_R, + MIPS_INS_SUBQ, + MIPS_INS_SUBQ_S, + MIPS_INS_SUBSUS_U, + MIPS_INS_SUBSUU_S, + MIPS_INS_SUBS_S, + MIPS_INS_SUBS_U, + MIPS_INS_SUBUH, + MIPS_INS_SUBUH_R, + MIPS_INS_SUBU, + MIPS_INS_SUBU_S, + MIPS_INS_SUBVI, + MIPS_INS_SUBV, + MIPS_INS_SUXC1, + MIPS_INS_SW, + MIPS_INS_SWC1, + MIPS_INS_SWC2, + MIPS_INS_SWC3, + MIPS_INS_SWL, + MIPS_INS_SWR, + MIPS_INS_SWXC1, + MIPS_INS_SYNC, + MIPS_INS_SYSCALL, + MIPS_INS_TEQ, + MIPS_INS_TEQI, + MIPS_INS_TGE, + MIPS_INS_TGEI, + MIPS_INS_TGEIU, + MIPS_INS_TGEU, + MIPS_INS_TLBP, + MIPS_INS_TLBR, + MIPS_INS_TLBWI, + MIPS_INS_TLBWR, + MIPS_INS_TLT, + MIPS_INS_TLTI, + MIPS_INS_TLTIU, + MIPS_INS_TLTU, + MIPS_INS_TNE, + MIPS_INS_TNEI, + MIPS_INS_TRUNC, + MIPS_INS_V3MULU, + MIPS_INS_VMM0, + MIPS_INS_VMULU, + MIPS_INS_VSHF, + MIPS_INS_WAIT, + MIPS_INS_WRDSP, + MIPS_INS_WSBH, + MIPS_INS_XOR, + MIPS_INS_XORI, + + //> some alias instructions + MIPS_INS_NOP, + MIPS_INS_NEGU, + + //> special instructions + MIPS_INS_JALR_HB, // jump and link with Hazard Barrier + MIPS_INS_JR_HB, // jump register with Hazard Barrier + + MIPS_INS_ENDING, +} mips_insn; + +//> Group of MIPS instructions +typedef enum mips_insn_group { + MIPS_GRP_INVALID = 0, // = CS_GRP_INVALID + + //> Generic groups + // all jump instructions (conditional+direct+indirect jumps) + MIPS_GRP_JUMP, // = CS_GRP_JUMP + + //> Architecture-specific groups + MIPS_GRP_BITCOUNT = 128, + MIPS_GRP_DSP, + MIPS_GRP_DSPR2, + MIPS_GRP_FPIDX, + MIPS_GRP_MSA, + MIPS_GRP_MIPS32R2, + MIPS_GRP_MIPS64, + MIPS_GRP_MIPS64R2, + MIPS_GRP_SEINREG, + MIPS_GRP_STDENC, + MIPS_GRP_SWAP, + MIPS_GRP_MICROMIPS, + MIPS_GRP_MIPS16MODE, + MIPS_GRP_FP64BIT, + MIPS_GRP_NONANSFPMATH, + MIPS_GRP_NOTFP64BIT, + MIPS_GRP_NOTINMICROMIPS, + MIPS_GRP_NOTNACL, + MIPS_GRP_NOTMIPS32R6, + MIPS_GRP_NOTMIPS64R6, + MIPS_GRP_CNMIPS, + MIPS_GRP_MIPS32, + MIPS_GRP_MIPS32R6, + MIPS_GRP_MIPS64R6, + MIPS_GRP_MIPS2, + MIPS_GRP_MIPS3, + MIPS_GRP_MIPS3_32, + MIPS_GRP_MIPS3_32R2, + MIPS_GRP_MIPS4_32, + MIPS_GRP_MIPS4_32R2, + MIPS_GRP_MIPS5_32R2, + MIPS_GRP_GP32BIT, + MIPS_GRP_GP64BIT, + + MIPS_GRP_ENDING, +} mips_insn_group; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/platform.h b/include/platform.h new file mode 100644 index 0000000..2ff28d3 --- /dev/null +++ b/include/platform.h @@ -0,0 +1,105 @@ +/* Capstone Disassembly Engine */ +/* By Axel Souchet & Nguyen Anh Quynh, 2014 */ + +#ifndef CAPSTONE_PLATFORM_H +#define CAPSTONE_PLATFORM_H + +// handle C99 issue (for pre-2013 VisualStudio) +#if !defined(__CYGWIN__) && !defined(__MINGW32__) && !defined(__MINGW64__) && (defined (WIN32) || defined (WIN64) || defined (_WIN32) || defined (_WIN64)) +// MSVC + +// stdbool.h +#if (_MSC_VER < 1800) || defined(_KERNEL_MODE) +// this system does not have stdbool.h +#ifndef __cplusplus +typedef unsigned char bool; +#define false 0 +#define true 1 +#endif + +#else +// VisualStudio 2013+ -> C99 is supported +#include +#endif + +#else +// not MSVC -> C99 is supported +#include +#endif + + +// handle C99 issue (for pre-2013 VisualStudio) +#if defined(CAPSTONE_HAS_OSXKERNEL) || (defined(_MSC_VER) && (_MSC_VER <= 1700 || defined(_KERNEL_MODE))) +// this system does not have inttypes.h + +#if defined(_MSC_VER) && (_MSC_VER <= 1700 || defined(_KERNEL_MODE)) +// this system does not have stdint.h +typedef signed char int8_t; +typedef signed short int16_t; +typedef signed int int32_t; +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +typedef signed long long int64_t; +typedef unsigned long long uint64_t; + +#define INT8_MIN (-127i8 - 1) +#define INT16_MIN (-32767i16 - 1) +#define INT32_MIN (-2147483647i32 - 1) +#define INT64_MIN (-9223372036854775807i64 - 1) +#define INT8_MAX 127i8 +#define INT16_MAX 32767i16 +#define INT32_MAX 2147483647i32 +#define INT64_MAX 9223372036854775807i64 +#define UINT8_MAX 0xffui8 +#define UINT16_MAX 0xffffui16 +#define UINT32_MAX 0xffffffffui32 +#define UINT64_MAX 0xffffffffffffffffui64 +#endif + +#define __PRI_8_LENGTH_MODIFIER__ "hh" +#define __PRI_64_LENGTH_MODIFIER__ "ll" + +#define PRId8 __PRI_8_LENGTH_MODIFIER__ "d" +#define PRIi8 __PRI_8_LENGTH_MODIFIER__ "i" +#define PRIo8 __PRI_8_LENGTH_MODIFIER__ "o" +#define PRIu8 __PRI_8_LENGTH_MODIFIER__ "u" +#define PRIx8 __PRI_8_LENGTH_MODIFIER__ "x" +#define PRIX8 __PRI_8_LENGTH_MODIFIER__ "X" + +#define PRId16 "hd" +#define PRIi16 "hi" +#define PRIo16 "ho" +#define PRIu16 "hu" +#define PRIx16 "hx" +#define PRIX16 "hX" + +#if defined(_MSC_VER) && _MSC_VER <= 1700 +#define PRId32 "ld" +#define PRIi32 "li" +#define PRIo32 "lo" +#define PRIu32 "lu" +#define PRIx32 "lx" +#define PRIX32 "lX" +#else // OSX +#define PRId32 "d" +#define PRIi32 "i" +#define PRIo32 "o" +#define PRIu32 "u" +#define PRIx32 "x" +#define PRIX32 "X" +#endif + +#define PRId64 __PRI_64_LENGTH_MODIFIER__ "d" +#define PRIi64 __PRI_64_LENGTH_MODIFIER__ "i" +#define PRIo64 __PRI_64_LENGTH_MODIFIER__ "o" +#define PRIu64 __PRI_64_LENGTH_MODIFIER__ "u" +#define PRIx64 __PRI_64_LENGTH_MODIFIER__ "x" +#define PRIX64 __PRI_64_LENGTH_MODIFIER__ "X" + +#else +// this system has inttypes.h by default +#include +#endif + +#endif diff --git a/include/ppc.h b/include/ppc.h new file mode 100644 index 0000000..b67df6d --- /dev/null +++ b/include/ppc.h @@ -0,0 +1,1254 @@ +#ifndef CAPSTONE_PPC_H +#define CAPSTONE_PPC_H + +/* Capstone Disassembly Engine */ +/* By Nguyen Anh Quynh , 2013-2014 */ + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(_MSC_VER) || !defined(_KERNEL_MODE) +#include +#endif + +#include "platform.h" + +#ifdef _MSC_VER +#pragma warning(disable:4201) +#endif + +//> PPC branch codes for some branch instructions +typedef enum ppc_bc { + PPC_BC_INVALID = 0, + PPC_BC_LT = (0 << 5) | 12, + PPC_BC_LE = (1 << 5) | 4, + PPC_BC_EQ = (2 << 5) | 12, + PPC_BC_GE = (0 << 5) | 4, + PPC_BC_GT = (1 << 5) | 12, + PPC_BC_NE = (2 << 5) | 4, + PPC_BC_UN = (3 << 5) | 12, + PPC_BC_NU = (3 << 5) | 4, + + // extra conditions + PPC_BC_SO = (4 << 5) | 12, // summary overflow + PPC_BC_NS = (4 << 5) | 4, // not summary overflow +} ppc_bc; + +//> PPC branch hint for some branch instructions +typedef enum ppc_bh { + PPC_BH_INVALID = 0, // no hint + PPC_BH_PLUS, // PLUS hint + PPC_BH_MINUS, // MINUS hint +} ppc_bh; + +//> PPC registers +typedef enum ppc_reg { + PPC_REG_INVALID = 0, + + PPC_REG_CARRY, + PPC_REG_CC, + PPC_REG_CR0, + PPC_REG_CR1, + PPC_REG_CR2, + PPC_REG_CR3, + PPC_REG_CR4, + PPC_REG_CR5, + PPC_REG_CR6, + PPC_REG_CR7, + PPC_REG_CTR, + PPC_REG_F0, + PPC_REG_F1, + PPC_REG_F2, + PPC_REG_F3, + PPC_REG_F4, + PPC_REG_F5, + PPC_REG_F6, + PPC_REG_F7, + PPC_REG_F8, + PPC_REG_F9, + PPC_REG_F10, + PPC_REG_F11, + PPC_REG_F12, + PPC_REG_F13, + PPC_REG_F14, + PPC_REG_F15, + PPC_REG_F16, + PPC_REG_F17, + PPC_REG_F18, + PPC_REG_F19, + PPC_REG_F20, + PPC_REG_F21, + PPC_REG_F22, + PPC_REG_F23, + PPC_REG_F24, + PPC_REG_F25, + PPC_REG_F26, + PPC_REG_F27, + PPC_REG_F28, + PPC_REG_F29, + PPC_REG_F30, + PPC_REG_F31, + PPC_REG_LR, + PPC_REG_R0, + PPC_REG_R1, + PPC_REG_R2, + PPC_REG_R3, + PPC_REG_R4, + PPC_REG_R5, + PPC_REG_R6, + PPC_REG_R7, + PPC_REG_R8, + PPC_REG_R9, + PPC_REG_R10, + PPC_REG_R11, + PPC_REG_R12, + PPC_REG_R13, + PPC_REG_R14, + PPC_REG_R15, + PPC_REG_R16, + PPC_REG_R17, + PPC_REG_R18, + PPC_REG_R19, + PPC_REG_R20, + PPC_REG_R21, + PPC_REG_R22, + PPC_REG_R23, + PPC_REG_R24, + PPC_REG_R25, + PPC_REG_R26, + PPC_REG_R27, + PPC_REG_R28, + PPC_REG_R29, + PPC_REG_R30, + PPC_REG_R31, + PPC_REG_V0, + PPC_REG_V1, + PPC_REG_V2, + PPC_REG_V3, + PPC_REG_V4, + PPC_REG_V5, + PPC_REG_V6, + PPC_REG_V7, + PPC_REG_V8, + PPC_REG_V9, + PPC_REG_V10, + PPC_REG_V11, + PPC_REG_V12, + PPC_REG_V13, + PPC_REG_V14, + PPC_REG_V15, + PPC_REG_V16, + PPC_REG_V17, + PPC_REG_V18, + PPC_REG_V19, + PPC_REG_V20, + PPC_REG_V21, + PPC_REG_V22, + PPC_REG_V23, + PPC_REG_V24, + PPC_REG_V25, + PPC_REG_V26, + PPC_REG_V27, + PPC_REG_V28, + PPC_REG_V29, + PPC_REG_V30, + PPC_REG_V31, + PPC_REG_VRSAVE, + PPC_REG_VS0, + PPC_REG_VS1, + PPC_REG_VS2, + PPC_REG_VS3, + PPC_REG_VS4, + PPC_REG_VS5, + PPC_REG_VS6, + PPC_REG_VS7, + PPC_REG_VS8, + PPC_REG_VS9, + PPC_REG_VS10, + PPC_REG_VS11, + PPC_REG_VS12, + PPC_REG_VS13, + PPC_REG_VS14, + PPC_REG_VS15, + PPC_REG_VS16, + PPC_REG_VS17, + PPC_REG_VS18, + PPC_REG_VS19, + PPC_REG_VS20, + PPC_REG_VS21, + PPC_REG_VS22, + PPC_REG_VS23, + PPC_REG_VS24, + PPC_REG_VS25, + PPC_REG_VS26, + PPC_REG_VS27, + PPC_REG_VS28, + PPC_REG_VS29, + PPC_REG_VS30, + PPC_REG_VS31, + PPC_REG_VS32, + PPC_REG_VS33, + PPC_REG_VS34, + PPC_REG_VS35, + PPC_REG_VS36, + PPC_REG_VS37, + PPC_REG_VS38, + PPC_REG_VS39, + PPC_REG_VS40, + PPC_REG_VS41, + PPC_REG_VS42, + PPC_REG_VS43, + PPC_REG_VS44, + PPC_REG_VS45, + PPC_REG_VS46, + PPC_REG_VS47, + PPC_REG_VS48, + PPC_REG_VS49, + PPC_REG_VS50, + PPC_REG_VS51, + PPC_REG_VS52, + PPC_REG_VS53, + PPC_REG_VS54, + PPC_REG_VS55, + PPC_REG_VS56, + PPC_REG_VS57, + PPC_REG_VS58, + PPC_REG_VS59, + PPC_REG_VS60, + PPC_REG_VS61, + PPC_REG_VS62, + PPC_REG_VS63, + + // extra registers for PPCMapping.c + PPC_REG_RM, + PPC_REG_CTR8, + PPC_REG_LR8, + PPC_REG_CR1EQ, + + PPC_REG_ENDING, // <-- mark the end of the list of registers +} ppc_reg; + +//> Operand type for instruction's operands +typedef enum ppc_op_type { + PPC_OP_INVALID = 0, // = CS_OP_INVALID (Uninitialized). + PPC_OP_REG, // = CS_OP_REG (Register operand). + PPC_OP_IMM, // = CS_OP_IMM (Immediate operand). + PPC_OP_MEM, // = CS_OP_MEM (Memory operand). + PPC_OP_CRX = 64, // Condition Register field +} ppc_op_type; + +// Instruction's operand referring to memory +// This is associated with PPC_OP_MEM operand type above +typedef struct ppc_op_mem { + ppc_reg base; // base register + int32_t disp; // displacement/offset value +} ppc_op_mem; + +typedef struct ppc_op_crx { + unsigned int scale; + ppc_reg reg; + ppc_bc cond; +} ppc_op_crx; + +// Instruction operand +typedef struct cs_ppc_op { + ppc_op_type type; // operand type + union { + ppc_reg reg; // register value for REG operand + int32_t imm; // immediate value for IMM operand + ppc_op_mem mem; // base/disp value for MEM operand + ppc_op_crx crx; // operand with condition register + }; +} cs_ppc_op; + +// Instruction structure +typedef struct cs_ppc { + // branch code for branch instructions + ppc_bc bc; + + // branch hint for branch instructions + ppc_bh bh; + + // if update_cr0 = True, then this 'dot' insn updates CR0 + bool update_cr0; + + // Number of operands of this instruction, + // or 0 when instruction has no operand. + uint8_t op_count; + cs_ppc_op operands[8]; // operands for this instruction. +} cs_ppc; + + +//> PPC instruction +typedef enum ppc_insn { + PPC_INS_INVALID = 0, + + PPC_INS_ADD, + PPC_INS_ADDC, + PPC_INS_ADDE, + PPC_INS_ADDI, + PPC_INS_ADDIC, + PPC_INS_ADDIS, + PPC_INS_ADDME, + PPC_INS_ADDZE, + PPC_INS_AND, + PPC_INS_ANDC, + PPC_INS_ANDIS, + PPC_INS_ANDI, + PPC_INS_B, + PPC_INS_BA, + PPC_INS_BC, + PPC_INS_BCCTR, + PPC_INS_BCCTRL, + PPC_INS_BCL, + PPC_INS_BCLR, + PPC_INS_BCLRL, + PPC_INS_BCTR, + PPC_INS_BCTRL, + PPC_INS_BDNZ, + PPC_INS_BDNZA, + PPC_INS_BDNZL, + PPC_INS_BDNZLA, + PPC_INS_BDNZLR, + PPC_INS_BDNZLRL, + PPC_INS_BDZ, + PPC_INS_BDZA, + PPC_INS_BDZL, + PPC_INS_BDZLA, + PPC_INS_BDZLR, + PPC_INS_BDZLRL, + PPC_INS_BL, + PPC_INS_BLA, + PPC_INS_BLR, + PPC_INS_BLRL, + PPC_INS_BRINC, + PPC_INS_CMPD, + PPC_INS_CMPDI, + PPC_INS_CMPLD, + PPC_INS_CMPLDI, + PPC_INS_CMPLW, + PPC_INS_CMPLWI, + PPC_INS_CMPW, + PPC_INS_CMPWI, + PPC_INS_CNTLZD, + PPC_INS_CNTLZW, + PPC_INS_CREQV, + PPC_INS_CRXOR, + PPC_INS_CRAND, + PPC_INS_CRANDC, + PPC_INS_CRNAND, + PPC_INS_CRNOR, + PPC_INS_CROR, + PPC_INS_CRORC, + PPC_INS_DCBA, + PPC_INS_DCBF, + PPC_INS_DCBI, + PPC_INS_DCBST, + PPC_INS_DCBT, + PPC_INS_DCBTST, + PPC_INS_DCBZ, + PPC_INS_DCBZL, + PPC_INS_DCCCI, + PPC_INS_DIVD, + PPC_INS_DIVDU, + PPC_INS_DIVW, + PPC_INS_DIVWU, + PPC_INS_DSS, + PPC_INS_DSSALL, + PPC_INS_DST, + PPC_INS_DSTST, + PPC_INS_DSTSTT, + PPC_INS_DSTT, + PPC_INS_EIEIO, + PPC_INS_EQV, + PPC_INS_EVABS, + PPC_INS_EVADDIW, + PPC_INS_EVADDSMIAAW, + PPC_INS_EVADDSSIAAW, + PPC_INS_EVADDUMIAAW, + PPC_INS_EVADDUSIAAW, + PPC_INS_EVADDW, + PPC_INS_EVAND, + PPC_INS_EVANDC, + PPC_INS_EVCMPEQ, + PPC_INS_EVCMPGTS, + PPC_INS_EVCMPGTU, + PPC_INS_EVCMPLTS, + PPC_INS_EVCMPLTU, + PPC_INS_EVCNTLSW, + PPC_INS_EVCNTLZW, + PPC_INS_EVDIVWS, + PPC_INS_EVDIVWU, + PPC_INS_EVEQV, + PPC_INS_EVEXTSB, + PPC_INS_EVEXTSH, + PPC_INS_EVLDD, + PPC_INS_EVLDDX, + PPC_INS_EVLDH, + PPC_INS_EVLDHX, + PPC_INS_EVLDW, + PPC_INS_EVLDWX, + PPC_INS_EVLHHESPLAT, + PPC_INS_EVLHHESPLATX, + PPC_INS_EVLHHOSSPLAT, + PPC_INS_EVLHHOSSPLATX, + PPC_INS_EVLHHOUSPLAT, + PPC_INS_EVLHHOUSPLATX, + PPC_INS_EVLWHE, + PPC_INS_EVLWHEX, + PPC_INS_EVLWHOS, + PPC_INS_EVLWHOSX, + PPC_INS_EVLWHOU, + PPC_INS_EVLWHOUX, + PPC_INS_EVLWHSPLAT, + PPC_INS_EVLWHSPLATX, + PPC_INS_EVLWWSPLAT, + PPC_INS_EVLWWSPLATX, + PPC_INS_EVMERGEHI, + PPC_INS_EVMERGEHILO, + PPC_INS_EVMERGELO, + PPC_INS_EVMERGELOHI, + PPC_INS_EVMHEGSMFAA, + PPC_INS_EVMHEGSMFAN, + PPC_INS_EVMHEGSMIAA, + PPC_INS_EVMHEGSMIAN, + PPC_INS_EVMHEGUMIAA, + PPC_INS_EVMHEGUMIAN, + PPC_INS_EVMHESMF, + PPC_INS_EVMHESMFA, + PPC_INS_EVMHESMFAAW, + PPC_INS_EVMHESMFANW, + PPC_INS_EVMHESMI, + PPC_INS_EVMHESMIA, + PPC_INS_EVMHESMIAAW, + PPC_INS_EVMHESMIANW, + PPC_INS_EVMHESSF, + PPC_INS_EVMHESSFA, + PPC_INS_EVMHESSFAAW, + PPC_INS_EVMHESSFANW, + PPC_INS_EVMHESSIAAW, + PPC_INS_EVMHESSIANW, + PPC_INS_EVMHEUMI, + PPC_INS_EVMHEUMIA, + PPC_INS_EVMHEUMIAAW, + PPC_INS_EVMHEUMIANW, + PPC_INS_EVMHEUSIAAW, + PPC_INS_EVMHEUSIANW, + PPC_INS_EVMHOGSMFAA, + PPC_INS_EVMHOGSMFAN, + PPC_INS_EVMHOGSMIAA, + PPC_INS_EVMHOGSMIAN, + PPC_INS_EVMHOGUMIAA, + PPC_INS_EVMHOGUMIAN, + PPC_INS_EVMHOSMF, + PPC_INS_EVMHOSMFA, + PPC_INS_EVMHOSMFAAW, + PPC_INS_EVMHOSMFANW, + PPC_INS_EVMHOSMI, + PPC_INS_EVMHOSMIA, + PPC_INS_EVMHOSMIAAW, + PPC_INS_EVMHOSMIANW, + PPC_INS_EVMHOSSF, + PPC_INS_EVMHOSSFA, + PPC_INS_EVMHOSSFAAW, + PPC_INS_EVMHOSSFANW, + PPC_INS_EVMHOSSIAAW, + PPC_INS_EVMHOSSIANW, + PPC_INS_EVMHOUMI, + PPC_INS_EVMHOUMIA, + PPC_INS_EVMHOUMIAAW, + PPC_INS_EVMHOUMIANW, + PPC_INS_EVMHOUSIAAW, + PPC_INS_EVMHOUSIANW, + PPC_INS_EVMRA, + PPC_INS_EVMWHSMF, + PPC_INS_EVMWHSMFA, + PPC_INS_EVMWHSMI, + PPC_INS_EVMWHSMIA, + PPC_INS_EVMWHSSF, + PPC_INS_EVMWHSSFA, + PPC_INS_EVMWHUMI, + PPC_INS_EVMWHUMIA, + PPC_INS_EVMWLSMIAAW, + PPC_INS_EVMWLSMIANW, + PPC_INS_EVMWLSSIAAW, + PPC_INS_EVMWLSSIANW, + PPC_INS_EVMWLUMI, + PPC_INS_EVMWLUMIA, + PPC_INS_EVMWLUMIAAW, + PPC_INS_EVMWLUMIANW, + PPC_INS_EVMWLUSIAAW, + PPC_INS_EVMWLUSIANW, + PPC_INS_EVMWSMF, + PPC_INS_EVMWSMFA, + PPC_INS_EVMWSMFAA, + PPC_INS_EVMWSMFAN, + PPC_INS_EVMWSMI, + PPC_INS_EVMWSMIA, + PPC_INS_EVMWSMIAA, + PPC_INS_EVMWSMIAN, + PPC_INS_EVMWSSF, + PPC_INS_EVMWSSFA, + PPC_INS_EVMWSSFAA, + PPC_INS_EVMWSSFAN, + PPC_INS_EVMWUMI, + PPC_INS_EVMWUMIA, + PPC_INS_EVMWUMIAA, + PPC_INS_EVMWUMIAN, + PPC_INS_EVNAND, + PPC_INS_EVNEG, + PPC_INS_EVNOR, + PPC_INS_EVOR, + PPC_INS_EVORC, + PPC_INS_EVRLW, + PPC_INS_EVRLWI, + PPC_INS_EVRNDW, + PPC_INS_EVSLW, + PPC_INS_EVSLWI, + PPC_INS_EVSPLATFI, + PPC_INS_EVSPLATI, + PPC_INS_EVSRWIS, + PPC_INS_EVSRWIU, + PPC_INS_EVSRWS, + PPC_INS_EVSRWU, + PPC_INS_EVSTDD, + PPC_INS_EVSTDDX, + PPC_INS_EVSTDH, + PPC_INS_EVSTDHX, + PPC_INS_EVSTDW, + PPC_INS_EVSTDWX, + PPC_INS_EVSTWHE, + PPC_INS_EVSTWHEX, + PPC_INS_EVSTWHO, + PPC_INS_EVSTWHOX, + PPC_INS_EVSTWWE, + PPC_INS_EVSTWWEX, + PPC_INS_EVSTWWO, + PPC_INS_EVSTWWOX, + PPC_INS_EVSUBFSMIAAW, + PPC_INS_EVSUBFSSIAAW, + PPC_INS_EVSUBFUMIAAW, + PPC_INS_EVSUBFUSIAAW, + PPC_INS_EVSUBFW, + PPC_INS_EVSUBIFW, + PPC_INS_EVXOR, + PPC_INS_EXTSB, + PPC_INS_EXTSH, + PPC_INS_EXTSW, + PPC_INS_FABS, + PPC_INS_FADD, + PPC_INS_FADDS, + PPC_INS_FCFID, + PPC_INS_FCFIDS, + PPC_INS_FCFIDU, + PPC_INS_FCFIDUS, + PPC_INS_FCMPU, + PPC_INS_FCPSGN, + PPC_INS_FCTID, + PPC_INS_FCTIDUZ, + PPC_INS_FCTIDZ, + PPC_INS_FCTIW, + PPC_INS_FCTIWUZ, + PPC_INS_FCTIWZ, + PPC_INS_FDIV, + PPC_INS_FDIVS, + PPC_INS_FMADD, + PPC_INS_FMADDS, + PPC_INS_FMR, + PPC_INS_FMSUB, + PPC_INS_FMSUBS, + PPC_INS_FMUL, + PPC_INS_FMULS, + PPC_INS_FNABS, + PPC_INS_FNEG, + PPC_INS_FNMADD, + PPC_INS_FNMADDS, + PPC_INS_FNMSUB, + PPC_INS_FNMSUBS, + PPC_INS_FRE, + PPC_INS_FRES, + PPC_INS_FRIM, + PPC_INS_FRIN, + PPC_INS_FRIP, + PPC_INS_FRIZ, + PPC_INS_FRSP, + PPC_INS_FRSQRTE, + PPC_INS_FRSQRTES, + PPC_INS_FSEL, + PPC_INS_FSQRT, + PPC_INS_FSQRTS, + PPC_INS_FSUB, + PPC_INS_FSUBS, + PPC_INS_ICBI, + PPC_INS_ICCCI, + PPC_INS_ISEL, + PPC_INS_ISYNC, + PPC_INS_LA, + PPC_INS_LBZ, + PPC_INS_LBZU, + PPC_INS_LBZUX, + PPC_INS_LBZX, + PPC_INS_LD, + PPC_INS_LDARX, + PPC_INS_LDBRX, + PPC_INS_LDU, + PPC_INS_LDUX, + PPC_INS_LDX, + PPC_INS_LFD, + PPC_INS_LFDU, + PPC_INS_LFDUX, + PPC_INS_LFDX, + PPC_INS_LFIWAX, + PPC_INS_LFIWZX, + PPC_INS_LFS, + PPC_INS_LFSU, + PPC_INS_LFSUX, + PPC_INS_LFSX, + PPC_INS_LHA, + PPC_INS_LHAU, + PPC_INS_LHAUX, + PPC_INS_LHAX, + PPC_INS_LHBRX, + PPC_INS_LHZ, + PPC_INS_LHZU, + PPC_INS_LHZUX, + PPC_INS_LHZX, + PPC_INS_LI, + PPC_INS_LIS, + PPC_INS_LMW, + PPC_INS_LSWI, + PPC_INS_LVEBX, + PPC_INS_LVEHX, + PPC_INS_LVEWX, + PPC_INS_LVSL, + PPC_INS_LVSR, + PPC_INS_LVX, + PPC_INS_LVXL, + PPC_INS_LWA, + PPC_INS_LWARX, + PPC_INS_LWAUX, + PPC_INS_LWAX, + PPC_INS_LWBRX, + PPC_INS_LWZ, + PPC_INS_LWZU, + PPC_INS_LWZUX, + PPC_INS_LWZX, + PPC_INS_LXSDX, + PPC_INS_LXVD2X, + PPC_INS_LXVDSX, + PPC_INS_LXVW4X, + PPC_INS_MBAR, + PPC_INS_MCRF, + PPC_INS_MFCR, + PPC_INS_MFCTR, + PPC_INS_MFDCR, + PPC_INS_MFFS, + PPC_INS_MFLR, + PPC_INS_MFMSR, + PPC_INS_MFOCRF, + PPC_INS_MFSPR, + PPC_INS_MFSR, + PPC_INS_MFSRIN, + PPC_INS_MFTB, + PPC_INS_MFVSCR, + PPC_INS_MSYNC, + PPC_INS_MTCRF, + PPC_INS_MTCTR, + PPC_INS_MTDCR, + PPC_INS_MTFSB0, + PPC_INS_MTFSB1, + PPC_INS_MTFSF, + PPC_INS_MTLR, + PPC_INS_MTMSR, + PPC_INS_MTMSRD, + PPC_INS_MTOCRF, + PPC_INS_MTSPR, + PPC_INS_MTSR, + PPC_INS_MTSRIN, + PPC_INS_MTVSCR, + PPC_INS_MULHD, + PPC_INS_MULHDU, + PPC_INS_MULHW, + PPC_INS_MULHWU, + PPC_INS_MULLD, + PPC_INS_MULLI, + PPC_INS_MULLW, + PPC_INS_NAND, + PPC_INS_NEG, + PPC_INS_NOP, + PPC_INS_ORI, + PPC_INS_NOR, + PPC_INS_OR, + PPC_INS_ORC, + PPC_INS_ORIS, + PPC_INS_POPCNTD, + PPC_INS_POPCNTW, + PPC_INS_RFCI, + PPC_INS_RFDI, + PPC_INS_RFI, + PPC_INS_RFID, + PPC_INS_RFMCI, + PPC_INS_RLDCL, + PPC_INS_RLDCR, + PPC_INS_RLDIC, + PPC_INS_RLDICL, + PPC_INS_RLDICR, + PPC_INS_RLDIMI, + PPC_INS_RLWIMI, + PPC_INS_RLWINM, + PPC_INS_RLWNM, + PPC_INS_SC, + PPC_INS_SLBIA, + PPC_INS_SLBIE, + PPC_INS_SLBMFEE, + PPC_INS_SLBMTE, + PPC_INS_SLD, + PPC_INS_SLW, + PPC_INS_SRAD, + PPC_INS_SRADI, + PPC_INS_SRAW, + PPC_INS_SRAWI, + PPC_INS_SRD, + PPC_INS_SRW, + PPC_INS_STB, + PPC_INS_STBU, + PPC_INS_STBUX, + PPC_INS_STBX, + PPC_INS_STD, + PPC_INS_STDBRX, + PPC_INS_STDCX, + PPC_INS_STDU, + PPC_INS_STDUX, + PPC_INS_STDX, + PPC_INS_STFD, + PPC_INS_STFDU, + PPC_INS_STFDUX, + PPC_INS_STFDX, + PPC_INS_STFIWX, + PPC_INS_STFS, + PPC_INS_STFSU, + PPC_INS_STFSUX, + PPC_INS_STFSX, + PPC_INS_STH, + PPC_INS_STHBRX, + PPC_INS_STHU, + PPC_INS_STHUX, + PPC_INS_STHX, + PPC_INS_STMW, + PPC_INS_STSWI, + PPC_INS_STVEBX, + PPC_INS_STVEHX, + PPC_INS_STVEWX, + PPC_INS_STVX, + PPC_INS_STVXL, + PPC_INS_STW, + PPC_INS_STWBRX, + PPC_INS_STWCX, + PPC_INS_STWU, + PPC_INS_STWUX, + PPC_INS_STWX, + PPC_INS_STXSDX, + PPC_INS_STXVD2X, + PPC_INS_STXVW4X, + PPC_INS_SUBF, + PPC_INS_SUBFC, + PPC_INS_SUBFE, + PPC_INS_SUBFIC, + PPC_INS_SUBFME, + PPC_INS_SUBFZE, + PPC_INS_SYNC, + PPC_INS_TD, + PPC_INS_TDI, + PPC_INS_TLBIA, + PPC_INS_TLBIE, + PPC_INS_TLBIEL, + PPC_INS_TLBIVAX, + PPC_INS_TLBLD, + PPC_INS_TLBLI, + PPC_INS_TLBRE, + PPC_INS_TLBSX, + PPC_INS_TLBSYNC, + PPC_INS_TLBWE, + PPC_INS_TRAP, + PPC_INS_TW, + PPC_INS_TWI, + PPC_INS_VADDCUW, + PPC_INS_VADDFP, + PPC_INS_VADDSBS, + PPC_INS_VADDSHS, + PPC_INS_VADDSWS, + PPC_INS_VADDUBM, + PPC_INS_VADDUBS, + PPC_INS_VADDUHM, + PPC_INS_VADDUHS, + PPC_INS_VADDUWM, + PPC_INS_VADDUWS, + PPC_INS_VAND, + PPC_INS_VANDC, + PPC_INS_VAVGSB, + PPC_INS_VAVGSH, + PPC_INS_VAVGSW, + PPC_INS_VAVGUB, + PPC_INS_VAVGUH, + PPC_INS_VAVGUW, + PPC_INS_VCFSX, + PPC_INS_VCFUX, + PPC_INS_VCMPBFP, + PPC_INS_VCMPEQFP, + PPC_INS_VCMPEQUB, + PPC_INS_VCMPEQUH, + PPC_INS_VCMPEQUW, + PPC_INS_VCMPGEFP, + PPC_INS_VCMPGTFP, + PPC_INS_VCMPGTSB, + PPC_INS_VCMPGTSH, + PPC_INS_VCMPGTSW, + PPC_INS_VCMPGTUB, + PPC_INS_VCMPGTUH, + PPC_INS_VCMPGTUW, + PPC_INS_VCTSXS, + PPC_INS_VCTUXS, + PPC_INS_VEXPTEFP, + PPC_INS_VLOGEFP, + PPC_INS_VMADDFP, + PPC_INS_VMAXFP, + PPC_INS_VMAXSB, + PPC_INS_VMAXSH, + PPC_INS_VMAXSW, + PPC_INS_VMAXUB, + PPC_INS_VMAXUH, + PPC_INS_VMAXUW, + PPC_INS_VMHADDSHS, + PPC_INS_VMHRADDSHS, + PPC_INS_VMINFP, + PPC_INS_VMINSB, + PPC_INS_VMINSH, + PPC_INS_VMINSW, + PPC_INS_VMINUB, + PPC_INS_VMINUH, + PPC_INS_VMINUW, + PPC_INS_VMLADDUHM, + PPC_INS_VMRGHB, + PPC_INS_VMRGHH, + PPC_INS_VMRGHW, + PPC_INS_VMRGLB, + PPC_INS_VMRGLH, + PPC_INS_VMRGLW, + PPC_INS_VMSUMMBM, + PPC_INS_VMSUMSHM, + PPC_INS_VMSUMSHS, + PPC_INS_VMSUMUBM, + PPC_INS_VMSUMUHM, + PPC_INS_VMSUMUHS, + PPC_INS_VMULESB, + PPC_INS_VMULESH, + PPC_INS_VMULEUB, + PPC_INS_VMULEUH, + PPC_INS_VMULOSB, + PPC_INS_VMULOSH, + PPC_INS_VMULOUB, + PPC_INS_VMULOUH, + PPC_INS_VNMSUBFP, + PPC_INS_VNOR, + PPC_INS_VOR, + PPC_INS_VPERM, + PPC_INS_VPKPX, + PPC_INS_VPKSHSS, + PPC_INS_VPKSHUS, + PPC_INS_VPKSWSS, + PPC_INS_VPKSWUS, + PPC_INS_VPKUHUM, + PPC_INS_VPKUHUS, + PPC_INS_VPKUWUM, + PPC_INS_VPKUWUS, + PPC_INS_VREFP, + PPC_INS_VRFIM, + PPC_INS_VRFIN, + PPC_INS_VRFIP, + PPC_INS_VRFIZ, + PPC_INS_VRLB, + PPC_INS_VRLH, + PPC_INS_VRLW, + PPC_INS_VRSQRTEFP, + PPC_INS_VSEL, + PPC_INS_VSL, + PPC_INS_VSLB, + PPC_INS_VSLDOI, + PPC_INS_VSLH, + PPC_INS_VSLO, + PPC_INS_VSLW, + PPC_INS_VSPLTB, + PPC_INS_VSPLTH, + PPC_INS_VSPLTISB, + PPC_INS_VSPLTISH, + PPC_INS_VSPLTISW, + PPC_INS_VSPLTW, + PPC_INS_VSR, + PPC_INS_VSRAB, + PPC_INS_VSRAH, + PPC_INS_VSRAW, + PPC_INS_VSRB, + PPC_INS_VSRH, + PPC_INS_VSRO, + PPC_INS_VSRW, + PPC_INS_VSUBCUW, + PPC_INS_VSUBFP, + PPC_INS_VSUBSBS, + PPC_INS_VSUBSHS, + PPC_INS_VSUBSWS, + PPC_INS_VSUBUBM, + PPC_INS_VSUBUBS, + PPC_INS_VSUBUHM, + PPC_INS_VSUBUHS, + PPC_INS_VSUBUWM, + PPC_INS_VSUBUWS, + PPC_INS_VSUM2SWS, + PPC_INS_VSUM4SBS, + PPC_INS_VSUM4SHS, + PPC_INS_VSUM4UBS, + PPC_INS_VSUMSWS, + PPC_INS_VUPKHPX, + PPC_INS_VUPKHSB, + PPC_INS_VUPKHSH, + PPC_INS_VUPKLPX, + PPC_INS_VUPKLSB, + PPC_INS_VUPKLSH, + PPC_INS_VXOR, + PPC_INS_WAIT, + PPC_INS_WRTEE, + PPC_INS_WRTEEI, + PPC_INS_XOR, + PPC_INS_XORI, + PPC_INS_XORIS, + PPC_INS_XSABSDP, + PPC_INS_XSADDDP, + PPC_INS_XSCMPODP, + PPC_INS_XSCMPUDP, + PPC_INS_XSCPSGNDP, + PPC_INS_XSCVDPSP, + PPC_INS_XSCVDPSXDS, + PPC_INS_XSCVDPSXWS, + PPC_INS_XSCVDPUXDS, + PPC_INS_XSCVDPUXWS, + PPC_INS_XSCVSPDP, + PPC_INS_XSCVSXDDP, + PPC_INS_XSCVUXDDP, + PPC_INS_XSDIVDP, + PPC_INS_XSMADDADP, + PPC_INS_XSMADDMDP, + PPC_INS_XSMAXDP, + PPC_INS_XSMINDP, + PPC_INS_XSMSUBADP, + PPC_INS_XSMSUBMDP, + PPC_INS_XSMULDP, + PPC_INS_XSNABSDP, + PPC_INS_XSNEGDP, + PPC_INS_XSNMADDADP, + PPC_INS_XSNMADDMDP, + PPC_INS_XSNMSUBADP, + PPC_INS_XSNMSUBMDP, + PPC_INS_XSRDPI, + PPC_INS_XSRDPIC, + PPC_INS_XSRDPIM, + PPC_INS_XSRDPIP, + PPC_INS_XSRDPIZ, + PPC_INS_XSREDP, + PPC_INS_XSRSQRTEDP, + PPC_INS_XSSQRTDP, + PPC_INS_XSSUBDP, + PPC_INS_XSTDIVDP, + PPC_INS_XSTSQRTDP, + PPC_INS_XVABSDP, + PPC_INS_XVABSSP, + PPC_INS_XVADDDP, + PPC_INS_XVADDSP, + PPC_INS_XVCMPEQDP, + PPC_INS_XVCMPEQSP, + PPC_INS_XVCMPGEDP, + PPC_INS_XVCMPGESP, + PPC_INS_XVCMPGTDP, + PPC_INS_XVCMPGTSP, + PPC_INS_XVCPSGNDP, + PPC_INS_XVCPSGNSP, + PPC_INS_XVCVDPSP, + PPC_INS_XVCVDPSXDS, + PPC_INS_XVCVDPSXWS, + PPC_INS_XVCVDPUXDS, + PPC_INS_XVCVDPUXWS, + PPC_INS_XVCVSPDP, + PPC_INS_XVCVSPSXDS, + PPC_INS_XVCVSPSXWS, + PPC_INS_XVCVSPUXDS, + PPC_INS_XVCVSPUXWS, + PPC_INS_XVCVSXDDP, + PPC_INS_XVCVSXDSP, + PPC_INS_XVCVSXWDP, + PPC_INS_XVCVSXWSP, + PPC_INS_XVCVUXDDP, + PPC_INS_XVCVUXDSP, + PPC_INS_XVCVUXWDP, + PPC_INS_XVCVUXWSP, + PPC_INS_XVDIVDP, + PPC_INS_XVDIVSP, + PPC_INS_XVMADDADP, + PPC_INS_XVMADDASP, + PPC_INS_XVMADDMDP, + PPC_INS_XVMADDMSP, + PPC_INS_XVMAXDP, + PPC_INS_XVMAXSP, + PPC_INS_XVMINDP, + PPC_INS_XVMINSP, + PPC_INS_XVMSUBADP, + PPC_INS_XVMSUBASP, + PPC_INS_XVMSUBMDP, + PPC_INS_XVMSUBMSP, + PPC_INS_XVMULDP, + PPC_INS_XVMULSP, + PPC_INS_XVNABSDP, + PPC_INS_XVNABSSP, + PPC_INS_XVNEGDP, + PPC_INS_XVNEGSP, + PPC_INS_XVNMADDADP, + PPC_INS_XVNMADDASP, + PPC_INS_XVNMADDMDP, + PPC_INS_XVNMADDMSP, + PPC_INS_XVNMSUBADP, + PPC_INS_XVNMSUBASP, + PPC_INS_XVNMSUBMDP, + PPC_INS_XVNMSUBMSP, + PPC_INS_XVRDPI, + PPC_INS_XVRDPIC, + PPC_INS_XVRDPIM, + PPC_INS_XVRDPIP, + PPC_INS_XVRDPIZ, + PPC_INS_XVREDP, + PPC_INS_XVRESP, + PPC_INS_XVRSPI, + PPC_INS_XVRSPIC, + PPC_INS_XVRSPIM, + PPC_INS_XVRSPIP, + PPC_INS_XVRSPIZ, + PPC_INS_XVRSQRTEDP, + PPC_INS_XVRSQRTESP, + PPC_INS_XVSQRTDP, + PPC_INS_XVSQRTSP, + PPC_INS_XVSUBDP, + PPC_INS_XVSUBSP, + PPC_INS_XVTDIVDP, + PPC_INS_XVTDIVSP, + PPC_INS_XVTSQRTDP, + PPC_INS_XVTSQRTSP, + PPC_INS_XXLAND, + PPC_INS_XXLANDC, + PPC_INS_XXLNOR, + PPC_INS_XXLOR, + PPC_INS_XXLXOR, + PPC_INS_XXMRGHW, + PPC_INS_XXMRGLW, + PPC_INS_XXPERMDI, + PPC_INS_XXSEL, + PPC_INS_XXSLDWI, + PPC_INS_XXSPLTW, + PPC_INS_BCA, + PPC_INS_BCLA, + + // extra & alias instructions + PPC_INS_SLWI, + PPC_INS_SRWI, + PPC_INS_SLDI, + + PPC_INS_BTA, + PPC_INS_CRSET, + PPC_INS_CRNOT, + PPC_INS_CRMOVE, + PPC_INS_CRCLR, + PPC_INS_MFBR0, + PPC_INS_MFBR1, + PPC_INS_MFBR2, + PPC_INS_MFBR3, + PPC_INS_MFBR4, + PPC_INS_MFBR5, + PPC_INS_MFBR6, + PPC_INS_MFBR7, + PPC_INS_MFXER, + PPC_INS_MFRTCU, + PPC_INS_MFRTCL, + PPC_INS_MFDSCR, + PPC_INS_MFDSISR, + PPC_INS_MFDAR, + PPC_INS_MFSRR2, + PPC_INS_MFSRR3, + PPC_INS_MFCFAR, + PPC_INS_MFAMR, + PPC_INS_MFPID, + PPC_INS_MFTBLO, + PPC_INS_MFTBHI, + PPC_INS_MFDBATU, + PPC_INS_MFDBATL, + PPC_INS_MFIBATU, + PPC_INS_MFIBATL, + PPC_INS_MFDCCR, + PPC_INS_MFICCR, + PPC_INS_MFDEAR, + PPC_INS_MFESR, + PPC_INS_MFSPEFSCR, + PPC_INS_MFTCR, + PPC_INS_MFASR, + PPC_INS_MFPVR, + PPC_INS_MFTBU, + PPC_INS_MTCR, + PPC_INS_MTBR0, + PPC_INS_MTBR1, + PPC_INS_MTBR2, + PPC_INS_MTBR3, + PPC_INS_MTBR4, + PPC_INS_MTBR5, + PPC_INS_MTBR6, + PPC_INS_MTBR7, + PPC_INS_MTXER, + PPC_INS_MTDSCR, + PPC_INS_MTDSISR, + PPC_INS_MTDAR, + PPC_INS_MTSRR2, + PPC_INS_MTSRR3, + PPC_INS_MTCFAR, + PPC_INS_MTAMR, + PPC_INS_MTPID, + PPC_INS_MTTBL, + PPC_INS_MTTBU, + PPC_INS_MTTBLO, + PPC_INS_MTTBHI, + PPC_INS_MTDBATU, + PPC_INS_MTDBATL, + PPC_INS_MTIBATU, + PPC_INS_MTIBATL, + PPC_INS_MTDCCR, + PPC_INS_MTICCR, + PPC_INS_MTDEAR, + PPC_INS_MTESR, + PPC_INS_MTSPEFSCR, + PPC_INS_MTTCR, + PPC_INS_NOT, + PPC_INS_MR, + PPC_INS_ROTLD, + PPC_INS_ROTLDI, + PPC_INS_CLRLDI, + PPC_INS_ROTLWI, + PPC_INS_CLRLWI, + PPC_INS_ROTLW, + PPC_INS_SUB, + PPC_INS_SUBC, + PPC_INS_LWSYNC, + PPC_INS_PTESYNC, + PPC_INS_TDLT, + PPC_INS_TDEQ, + PPC_INS_TDGT, + PPC_INS_TDNE, + PPC_INS_TDLLT, + PPC_INS_TDLGT, + PPC_INS_TDU, + PPC_INS_TDLTI, + PPC_INS_TDEQI, + PPC_INS_TDGTI, + PPC_INS_TDNEI, + PPC_INS_TDLLTI, + PPC_INS_TDLGTI, + PPC_INS_TDUI, + PPC_INS_TLBREHI, + PPC_INS_TLBRELO, + PPC_INS_TLBWEHI, + PPC_INS_TLBWELO, + PPC_INS_TWLT, + PPC_INS_TWEQ, + PPC_INS_TWGT, + PPC_INS_TWNE, + PPC_INS_TWLLT, + PPC_INS_TWLGT, + PPC_INS_TWU, + PPC_INS_TWLTI, + PPC_INS_TWEQI, + PPC_INS_TWGTI, + PPC_INS_TWNEI, + PPC_INS_TWLLTI, + PPC_INS_TWLGTI, + PPC_INS_TWUI, + PPC_INS_WAITRSV, + PPC_INS_WAITIMPL, + PPC_INS_XNOP, + PPC_INS_XVMOVDP, + PPC_INS_XVMOVSP, + PPC_INS_XXSPLTD, + PPC_INS_XXMRGHD, + PPC_INS_XXMRGLD, + PPC_INS_XXSWAPD, + PPC_INS_BT, + PPC_INS_BF, + PPC_INS_BDNZT, + PPC_INS_BDNZF, + PPC_INS_BDZF, + PPC_INS_BDZT, + PPC_INS_BFA, + PPC_INS_BDNZTA, + PPC_INS_BDNZFA, + PPC_INS_BDZTA, + PPC_INS_BDZFA, + PPC_INS_BTCTR, + PPC_INS_BFCTR, + PPC_INS_BTCTRL, + PPC_INS_BFCTRL, + PPC_INS_BTL, + PPC_INS_BFL, + PPC_INS_BDNZTL, + PPC_INS_BDNZFL, + PPC_INS_BDZTL, + PPC_INS_BDZFL, + PPC_INS_BTLA, + PPC_INS_BFLA, + PPC_INS_BDNZTLA, + PPC_INS_BDNZFLA, + PPC_INS_BDZTLA, + PPC_INS_BDZFLA, + PPC_INS_BTLR, + PPC_INS_BFLR, + PPC_INS_BDNZTLR, + PPC_INS_BDZTLR, + PPC_INS_BDZFLR, + PPC_INS_BTLRL, + PPC_INS_BFLRL, + PPC_INS_BDNZTLRL, + PPC_INS_BDNZFLRL, + PPC_INS_BDZTLRL, + PPC_INS_BDZFLRL, + + PPC_INS_ENDING, // <-- mark the end of the list of instructions +} ppc_insn; + +//> Group of PPC instructions +typedef enum ppc_insn_group { + PPC_GRP_INVALID = 0, // = CS_GRP_INVALID + + //> Generic groups + // all jump instructions (conditional+direct+indirect jumps) + PPC_GRP_JUMP, // = CS_GRP_JUMP + + //> Architecture-specific groups + PPC_GRP_ALTIVEC = 128, + PPC_GRP_MODE32, + PPC_GRP_MODE64, + PPC_GRP_BOOKE, + PPC_GRP_NOTBOOKE, + PPC_GRP_SPE, + PPC_GRP_VSX, + PPC_GRP_E500, + PPC_GRP_PPC4XX, + PPC_GRP_PPC6XX, + + PPC_GRP_ENDING, // <-- mark the end of the list of groups +} ppc_insn_group; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/sparc.h b/include/sparc.h new file mode 100644 index 0000000..a1fccfa --- /dev/null +++ b/include/sparc.h @@ -0,0 +1,522 @@ +#ifndef CAPSTONE_SPARC_H +#define CAPSTONE_SPARC_H + +/* Capstone Disassembly Engine */ +/* By Nguyen Anh Quynh , 2014 */ + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(_MSC_VER) || !defined(_KERNEL_MODE) +#include +#endif + +#include "platform.h" + +// GCC SPARC toolchain has a default macro called "sparc" which breaks +// compilation +#undef sparc + +#ifdef _MSC_VER +#pragma warning(disable:4201) +#endif + +//> Enums corresponding to Sparc condition codes, both icc's and fcc's. +typedef enum sparc_cc { + SPARC_CC_INVALID = 0, // invalid CC (default) + //> Integer condition codes + SPARC_CC_ICC_A = 8+256, // Always + SPARC_CC_ICC_N = 0+256, // Never + SPARC_CC_ICC_NE = 9+256, // Not Equal + SPARC_CC_ICC_E = 1+256, // Equal + SPARC_CC_ICC_G = 10+256, // Greater + SPARC_CC_ICC_LE = 2+256, // Less or Equal + SPARC_CC_ICC_GE = 11+256, // Greater or Equal + SPARC_CC_ICC_L = 3+256, // Less + SPARC_CC_ICC_GU = 12+256, // Greater Unsigned + SPARC_CC_ICC_LEU = 4+256, // Less or Equal Unsigned + SPARC_CC_ICC_CC = 13+256, // Carry Clear/Great or Equal Unsigned + SPARC_CC_ICC_CS = 5+256, // Carry Set/Less Unsigned + SPARC_CC_ICC_POS = 14+256, // Positive + SPARC_CC_ICC_NEG = 6+256, // Negative + SPARC_CC_ICC_VC = 15+256, // Overflow Clear + SPARC_CC_ICC_VS = 7+256, // Overflow Set + + //> Floating condition codes + SPARC_CC_FCC_A = 8+16+256, // Always + SPARC_CC_FCC_N = 0+16+256, // Never + SPARC_CC_FCC_U = 7+16+256, // Unordered + SPARC_CC_FCC_G = 6+16+256, // Greater + SPARC_CC_FCC_UG = 5+16+256, // Unordered or Greater + SPARC_CC_FCC_L = 4+16+256, // Less + SPARC_CC_FCC_UL = 3+16+256, // Unordered or Less + SPARC_CC_FCC_LG = 2+16+256, // Less or Greater + SPARC_CC_FCC_NE = 1+16+256, // Not Equal + SPARC_CC_FCC_E = 9+16+256, // Equal + SPARC_CC_FCC_UE = 10+16+256, // Unordered or Equal + SPARC_CC_FCC_GE = 11+16+256, // Greater or Equal + SPARC_CC_FCC_UGE = 12+16+256, // Unordered or Greater or Equal + SPARC_CC_FCC_LE = 13+16+256, // Less or Equal + SPARC_CC_FCC_ULE = 14+16+256, // Unordered or Less or Equal + SPARC_CC_FCC_O = 15+16+256, // Ordered +} sparc_cc; + +//> Branch hint +typedef enum sparc_hint { + SPARC_HINT_INVALID = 0, // no hint + SPARC_HINT_A = 1 << 0, // annul delay slot instruction + SPARC_HINT_PT = 1 << 1, // branch taken + SPARC_HINT_PN = 1 << 2, // branch NOT taken +} sparc_hint; + +//> Operand type for instruction's operands +typedef enum sparc_op_type { + SPARC_OP_INVALID = 0, // = CS_OP_INVALID (Uninitialized). + SPARC_OP_REG, // = CS_OP_REG (Register operand). + SPARC_OP_IMM, // = CS_OP_IMM (Immediate operand). + SPARC_OP_MEM, // = CS_OP_MEM (Memory operand). +} sparc_op_type; + +// Instruction's operand referring to memory +// This is associated with SPARC_OP_MEM operand type above +typedef struct sparc_op_mem { + uint8_t base; // base register + uint8_t index; // index register + int32_t disp; // displacement/offset value +} sparc_op_mem; + +// Instruction operand +typedef struct cs_sparc_op { + sparc_op_type type; // operand type + union { + unsigned int reg; // register value for REG operand + int32_t imm; // immediate value for IMM operand + sparc_op_mem mem; // base/disp value for MEM operand + }; +} cs_sparc_op; + +// Instruction structure +typedef struct cs_sparc { + sparc_cc cc; // code condition for this insn + sparc_hint hint; // branch hint: encoding as bitwise OR of sparc_hint. + // Number of operands of this instruction, + // or 0 when instruction has no operand. + uint8_t op_count; + cs_sparc_op operands[4]; // operands for this instruction. +} cs_sparc; + +//> SPARC registers +typedef enum sparc_reg { + SPARC_REG_INVALID = 0, + + SPARC_REG_F0, + SPARC_REG_F1, + SPARC_REG_F2, + SPARC_REG_F3, + SPARC_REG_F4, + SPARC_REG_F5, + SPARC_REG_F6, + SPARC_REG_F7, + SPARC_REG_F8, + SPARC_REG_F9, + SPARC_REG_F10, + SPARC_REG_F11, + SPARC_REG_F12, + SPARC_REG_F13, + SPARC_REG_F14, + SPARC_REG_F15, + SPARC_REG_F16, + SPARC_REG_F17, + SPARC_REG_F18, + SPARC_REG_F19, + SPARC_REG_F20, + SPARC_REG_F21, + SPARC_REG_F22, + SPARC_REG_F23, + SPARC_REG_F24, + SPARC_REG_F25, + SPARC_REG_F26, + SPARC_REG_F27, + SPARC_REG_F28, + SPARC_REG_F29, + SPARC_REG_F30, + SPARC_REG_F31, + SPARC_REG_F32, + SPARC_REG_F34, + SPARC_REG_F36, + SPARC_REG_F38, + SPARC_REG_F40, + SPARC_REG_F42, + SPARC_REG_F44, + SPARC_REG_F46, + SPARC_REG_F48, + SPARC_REG_F50, + SPARC_REG_F52, + SPARC_REG_F54, + SPARC_REG_F56, + SPARC_REG_F58, + SPARC_REG_F60, + SPARC_REG_F62, + SPARC_REG_FCC0, // Floating condition codes + SPARC_REG_FCC1, + SPARC_REG_FCC2, + SPARC_REG_FCC3, + SPARC_REG_FP, + SPARC_REG_G0, + SPARC_REG_G1, + SPARC_REG_G2, + SPARC_REG_G3, + SPARC_REG_G4, + SPARC_REG_G5, + SPARC_REG_G6, + SPARC_REG_G7, + SPARC_REG_I0, + SPARC_REG_I1, + SPARC_REG_I2, + SPARC_REG_I3, + SPARC_REG_I4, + SPARC_REG_I5, + SPARC_REG_I7, + SPARC_REG_ICC, // Integer condition codes + SPARC_REG_L0, + SPARC_REG_L1, + SPARC_REG_L2, + SPARC_REG_L3, + SPARC_REG_L4, + SPARC_REG_L5, + SPARC_REG_L6, + SPARC_REG_L7, + SPARC_REG_O0, + SPARC_REG_O1, + SPARC_REG_O2, + SPARC_REG_O3, + SPARC_REG_O4, + SPARC_REG_O5, + SPARC_REG_O7, + SPARC_REG_SP, + SPARC_REG_Y, + + // special register + SPARC_REG_XCC, + + SPARC_REG_ENDING, // <-- mark the end of the list of registers + + // extras + SPARC_REG_O6 = SPARC_REG_SP, + SPARC_REG_I6 = SPARC_REG_FP, +} sparc_reg; + +//> SPARC instruction +typedef enum sparc_insn { + SPARC_INS_INVALID = 0, + + SPARC_INS_ADDCC, + SPARC_INS_ADDX, + SPARC_INS_ADDXCC, + SPARC_INS_ADDXC, + SPARC_INS_ADDXCCC, + SPARC_INS_ADD, + SPARC_INS_ALIGNADDR, + SPARC_INS_ALIGNADDRL, + SPARC_INS_ANDCC, + SPARC_INS_ANDNCC, + SPARC_INS_ANDN, + SPARC_INS_AND, + SPARC_INS_ARRAY16, + SPARC_INS_ARRAY32, + SPARC_INS_ARRAY8, + SPARC_INS_B, + SPARC_INS_JMP, + SPARC_INS_BMASK, + SPARC_INS_FB, + SPARC_INS_BRGEZ, + SPARC_INS_BRGZ, + SPARC_INS_BRLEZ, + SPARC_INS_BRLZ, + SPARC_INS_BRNZ, + SPARC_INS_BRZ, + SPARC_INS_BSHUFFLE, + SPARC_INS_CALL, + SPARC_INS_CASX, + SPARC_INS_CAS, + SPARC_INS_CMASK16, + SPARC_INS_CMASK32, + SPARC_INS_CMASK8, + SPARC_INS_CMP, + SPARC_INS_EDGE16, + SPARC_INS_EDGE16L, + SPARC_INS_EDGE16LN, + SPARC_INS_EDGE16N, + SPARC_INS_EDGE32, + SPARC_INS_EDGE32L, + SPARC_INS_EDGE32LN, + SPARC_INS_EDGE32N, + SPARC_INS_EDGE8, + SPARC_INS_EDGE8L, + SPARC_INS_EDGE8LN, + SPARC_INS_EDGE8N, + SPARC_INS_FABSD, + SPARC_INS_FABSQ, + SPARC_INS_FABSS, + SPARC_INS_FADDD, + SPARC_INS_FADDQ, + SPARC_INS_FADDS, + SPARC_INS_FALIGNDATA, + SPARC_INS_FAND, + SPARC_INS_FANDNOT1, + SPARC_INS_FANDNOT1S, + SPARC_INS_FANDNOT2, + SPARC_INS_FANDNOT2S, + SPARC_INS_FANDS, + SPARC_INS_FCHKSM16, + SPARC_INS_FCMPD, + SPARC_INS_FCMPEQ16, + SPARC_INS_FCMPEQ32, + SPARC_INS_FCMPGT16, + SPARC_INS_FCMPGT32, + SPARC_INS_FCMPLE16, + SPARC_INS_FCMPLE32, + SPARC_INS_FCMPNE16, + SPARC_INS_FCMPNE32, + SPARC_INS_FCMPQ, + SPARC_INS_FCMPS, + SPARC_INS_FDIVD, + SPARC_INS_FDIVQ, + SPARC_INS_FDIVS, + SPARC_INS_FDMULQ, + SPARC_INS_FDTOI, + SPARC_INS_FDTOQ, + SPARC_INS_FDTOS, + SPARC_INS_FDTOX, + SPARC_INS_FEXPAND, + SPARC_INS_FHADDD, + SPARC_INS_FHADDS, + SPARC_INS_FHSUBD, + SPARC_INS_FHSUBS, + SPARC_INS_FITOD, + SPARC_INS_FITOQ, + SPARC_INS_FITOS, + SPARC_INS_FLCMPD, + SPARC_INS_FLCMPS, + SPARC_INS_FLUSHW, + SPARC_INS_FMEAN16, + SPARC_INS_FMOVD, + SPARC_INS_FMOVQ, + SPARC_INS_FMOVRDGEZ, + SPARC_INS_FMOVRQGEZ, + SPARC_INS_FMOVRSGEZ, + SPARC_INS_FMOVRDGZ, + SPARC_INS_FMOVRQGZ, + SPARC_INS_FMOVRSGZ, + SPARC_INS_FMOVRDLEZ, + SPARC_INS_FMOVRQLEZ, + SPARC_INS_FMOVRSLEZ, + SPARC_INS_FMOVRDLZ, + SPARC_INS_FMOVRQLZ, + SPARC_INS_FMOVRSLZ, + SPARC_INS_FMOVRDNZ, + SPARC_INS_FMOVRQNZ, + SPARC_INS_FMOVRSNZ, + SPARC_INS_FMOVRDZ, + SPARC_INS_FMOVRQZ, + SPARC_INS_FMOVRSZ, + SPARC_INS_FMOVS, + SPARC_INS_FMUL8SUX16, + SPARC_INS_FMUL8ULX16, + SPARC_INS_FMUL8X16, + SPARC_INS_FMUL8X16AL, + SPARC_INS_FMUL8X16AU, + SPARC_INS_FMULD, + SPARC_INS_FMULD8SUX16, + SPARC_INS_FMULD8ULX16, + SPARC_INS_FMULQ, + SPARC_INS_FMULS, + SPARC_INS_FNADDD, + SPARC_INS_FNADDS, + SPARC_INS_FNAND, + SPARC_INS_FNANDS, + SPARC_INS_FNEGD, + SPARC_INS_FNEGQ, + SPARC_INS_FNEGS, + SPARC_INS_FNHADDD, + SPARC_INS_FNHADDS, + SPARC_INS_FNOR, + SPARC_INS_FNORS, + SPARC_INS_FNOT1, + SPARC_INS_FNOT1S, + SPARC_INS_FNOT2, + SPARC_INS_FNOT2S, + SPARC_INS_FONE, + SPARC_INS_FONES, + SPARC_INS_FOR, + SPARC_INS_FORNOT1, + SPARC_INS_FORNOT1S, + SPARC_INS_FORNOT2, + SPARC_INS_FORNOT2S, + SPARC_INS_FORS, + SPARC_INS_FPACK16, + SPARC_INS_FPACK32, + SPARC_INS_FPACKFIX, + SPARC_INS_FPADD16, + SPARC_INS_FPADD16S, + SPARC_INS_FPADD32, + SPARC_INS_FPADD32S, + SPARC_INS_FPADD64, + SPARC_INS_FPMERGE, + SPARC_INS_FPSUB16, + SPARC_INS_FPSUB16S, + SPARC_INS_FPSUB32, + SPARC_INS_FPSUB32S, + SPARC_INS_FQTOD, + SPARC_INS_FQTOI, + SPARC_INS_FQTOS, + SPARC_INS_FQTOX, + SPARC_INS_FSLAS16, + SPARC_INS_FSLAS32, + SPARC_INS_FSLL16, + SPARC_INS_FSLL32, + SPARC_INS_FSMULD, + SPARC_INS_FSQRTD, + SPARC_INS_FSQRTQ, + SPARC_INS_FSQRTS, + SPARC_INS_FSRA16, + SPARC_INS_FSRA32, + SPARC_INS_FSRC1, + SPARC_INS_FSRC1S, + SPARC_INS_FSRC2, + SPARC_INS_FSRC2S, + SPARC_INS_FSRL16, + SPARC_INS_FSRL32, + SPARC_INS_FSTOD, + SPARC_INS_FSTOI, + SPARC_INS_FSTOQ, + SPARC_INS_FSTOX, + SPARC_INS_FSUBD, + SPARC_INS_FSUBQ, + SPARC_INS_FSUBS, + SPARC_INS_FXNOR, + SPARC_INS_FXNORS, + SPARC_INS_FXOR, + SPARC_INS_FXORS, + SPARC_INS_FXTOD, + SPARC_INS_FXTOQ, + SPARC_INS_FXTOS, + SPARC_INS_FZERO, + SPARC_INS_FZEROS, + SPARC_INS_JMPL, + SPARC_INS_LDD, + SPARC_INS_LD, + SPARC_INS_LDQ, + SPARC_INS_LDSB, + SPARC_INS_LDSH, + SPARC_INS_LDSW, + SPARC_INS_LDUB, + SPARC_INS_LDUH, + SPARC_INS_LDX, + SPARC_INS_LZCNT, + SPARC_INS_MEMBAR, + SPARC_INS_MOVDTOX, + SPARC_INS_MOV, + SPARC_INS_MOVRGEZ, + SPARC_INS_MOVRGZ, + SPARC_INS_MOVRLEZ, + SPARC_INS_MOVRLZ, + SPARC_INS_MOVRNZ, + SPARC_INS_MOVRZ, + SPARC_INS_MOVSTOSW, + SPARC_INS_MOVSTOUW, + SPARC_INS_MULX, + SPARC_INS_NOP, + SPARC_INS_ORCC, + SPARC_INS_ORNCC, + SPARC_INS_ORN, + SPARC_INS_OR, + SPARC_INS_PDIST, + SPARC_INS_PDISTN, + SPARC_INS_POPC, + SPARC_INS_RD, + SPARC_INS_RESTORE, + SPARC_INS_RETT, + SPARC_INS_SAVE, + SPARC_INS_SDIVCC, + SPARC_INS_SDIVX, + SPARC_INS_SDIV, + SPARC_INS_SETHI, + SPARC_INS_SHUTDOWN, + SPARC_INS_SIAM, + SPARC_INS_SLLX, + SPARC_INS_SLL, + SPARC_INS_SMULCC, + SPARC_INS_SMUL, + SPARC_INS_SRAX, + SPARC_INS_SRA, + SPARC_INS_SRLX, + SPARC_INS_SRL, + SPARC_INS_STBAR, + SPARC_INS_STB, + SPARC_INS_STD, + SPARC_INS_ST, + SPARC_INS_STH, + SPARC_INS_STQ, + SPARC_INS_STX, + SPARC_INS_SUBCC, + SPARC_INS_SUBX, + SPARC_INS_SUBXCC, + SPARC_INS_SUB, + SPARC_INS_SWAP, + SPARC_INS_TADDCCTV, + SPARC_INS_TADDCC, + SPARC_INS_T, + SPARC_INS_TSUBCCTV, + SPARC_INS_TSUBCC, + SPARC_INS_UDIVCC, + SPARC_INS_UDIVX, + SPARC_INS_UDIV, + SPARC_INS_UMULCC, + SPARC_INS_UMULXHI, + SPARC_INS_UMUL, + SPARC_INS_UNIMP, + SPARC_INS_FCMPED, + SPARC_INS_FCMPEQ, + SPARC_INS_FCMPES, + SPARC_INS_WR, + SPARC_INS_XMULX, + SPARC_INS_XMULXHI, + SPARC_INS_XNORCC, + SPARC_INS_XNOR, + SPARC_INS_XORCC, + SPARC_INS_XOR, + + // alias instructions + SPARC_INS_RET, + SPARC_INS_RETL, + + SPARC_INS_ENDING, // <-- mark the end of the list of instructions +} sparc_insn; + +//> Group of SPARC instructions +typedef enum sparc_insn_group { + SPARC_GRP_INVALID = 0, // = CS_GRP_INVALID + + //> Generic groups + // all jump instructions (conditional+direct+indirect jumps) + SPARC_GRP_JUMP, // = CS_GRP_JUMP + + //> Architecture-specific groups + SPARC_GRP_HARDQUAD = 128, + SPARC_GRP_V9, + SPARC_GRP_VIS, + SPARC_GRP_VIS2, + SPARC_GRP_VIS3, + SPARC_GRP_32BIT, + SPARC_GRP_64BIT, + + SPARC_GRP_ENDING, // <-- mark the end of the list of groups +} sparc_insn_group; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/systemz.h b/include/systemz.h new file mode 100644 index 0000000..3020bd7 --- /dev/null +++ b/include/systemz.h @@ -0,0 +1,832 @@ +#ifndef CAPSTONE_SYSTEMZ_H +#define CAPSTONE_SYSTEMZ_H + +/* Capstone Disassembly Engine */ +/* By Nguyen Anh Quynh , 2014 */ + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(_MSC_VER) || !defined(_KERNEL_MODE) +#include +#endif + +#include "platform.h" + +#ifdef _MSC_VER +#pragma warning(disable:4201) +#endif + +//> Enums corresponding to SystemZ condition codes +typedef enum sysz_cc { + SYSZ_CC_INVALID = 0, // invalid CC (default) + + SYSZ_CC_O, + SYSZ_CC_H, + SYSZ_CC_NLE, + SYSZ_CC_L, + SYSZ_CC_NHE, + SYSZ_CC_LH, + SYSZ_CC_NE, + SYSZ_CC_E, + SYSZ_CC_NLH, + SYSZ_CC_HE, + SYSZ_CC_NL, + SYSZ_CC_LE, + SYSZ_CC_NH, + SYSZ_CC_NO, +} sysz_cc; + +//> Operand type for instruction's operands +typedef enum sysz_op_type { + SYSZ_OP_INVALID = 0, // = CS_OP_INVALID (Uninitialized). + SYSZ_OP_REG, // = CS_OP_REG (Register operand). + SYSZ_OP_IMM, // = CS_OP_IMM (Immediate operand). + SYSZ_OP_MEM, // = CS_OP_MEM (Memory operand). + SYSZ_OP_ACREG = 64, // Access register operand. +} sysz_op_type; + +// Instruction's operand referring to memory +// This is associated with SYSZ_OP_MEM operand type above +typedef struct sysz_op_mem { + uint8_t base; // base register + uint8_t index; // index register + uint64_t length; // BDLAddr operand + int64_t disp; // displacement/offset value +} sysz_op_mem; + +// Instruction operand +typedef struct cs_sysz_op { + sysz_op_type type; // operand type + union { + unsigned int reg; // register value for REG operand + int64_t imm; // immediate value for IMM operand + sysz_op_mem mem; // base/disp value for MEM operand + }; +} cs_sysz_op; + +// Instruction structure +typedef struct cs_sysz { + sysz_cc cc; // Code condition + // Number of operands of this instruction, + // or 0 when instruction has no operand. + uint8_t op_count; + cs_sysz_op operands[6]; // operands for this instruction. +} cs_sysz; + +//> SystemZ registers +typedef enum sysz_reg { + SYSZ_REG_INVALID = 0, + + SYSZ_REG_0, + SYSZ_REG_1, + SYSZ_REG_2, + SYSZ_REG_3, + SYSZ_REG_4, + SYSZ_REG_5, + SYSZ_REG_6, + SYSZ_REG_7, + SYSZ_REG_8, + SYSZ_REG_9, + SYSZ_REG_10, + SYSZ_REG_11, + SYSZ_REG_12, + SYSZ_REG_13, + SYSZ_REG_14, + SYSZ_REG_15, + SYSZ_REG_CC, + SYSZ_REG_F0, + SYSZ_REG_F1, + SYSZ_REG_F2, + SYSZ_REG_F3, + SYSZ_REG_F4, + SYSZ_REG_F5, + SYSZ_REG_F6, + SYSZ_REG_F7, + SYSZ_REG_F8, + SYSZ_REG_F9, + SYSZ_REG_F10, + SYSZ_REG_F11, + SYSZ_REG_F12, + SYSZ_REG_F13, + SYSZ_REG_F14, + SYSZ_REG_F15, + + SYSZ_REG_R0L, + + SYSZ_REG_ENDING, +} sysz_reg; + +//> SystemZ instruction +typedef enum sysz_insn { + SYSZ_INS_INVALID = 0, + + SYSZ_INS_A, + SYSZ_INS_ADB, + SYSZ_INS_ADBR, + SYSZ_INS_AEB, + SYSZ_INS_AEBR, + SYSZ_INS_AFI, + SYSZ_INS_AG, + SYSZ_INS_AGF, + SYSZ_INS_AGFI, + SYSZ_INS_AGFR, + SYSZ_INS_AGHI, + SYSZ_INS_AGHIK, + SYSZ_INS_AGR, + SYSZ_INS_AGRK, + SYSZ_INS_AGSI, + SYSZ_INS_AH, + SYSZ_INS_AHI, + SYSZ_INS_AHIK, + SYSZ_INS_AHY, + SYSZ_INS_AIH, + SYSZ_INS_AL, + SYSZ_INS_ALC, + SYSZ_INS_ALCG, + SYSZ_INS_ALCGR, + SYSZ_INS_ALCR, + SYSZ_INS_ALFI, + SYSZ_INS_ALG, + SYSZ_INS_ALGF, + SYSZ_INS_ALGFI, + SYSZ_INS_ALGFR, + SYSZ_INS_ALGHSIK, + SYSZ_INS_ALGR, + SYSZ_INS_ALGRK, + SYSZ_INS_ALHSIK, + SYSZ_INS_ALR, + SYSZ_INS_ALRK, + SYSZ_INS_ALY, + SYSZ_INS_AR, + SYSZ_INS_ARK, + SYSZ_INS_ASI, + SYSZ_INS_AXBR, + SYSZ_INS_AY, + SYSZ_INS_BCR, + SYSZ_INS_BRC, + SYSZ_INS_BRCL, + SYSZ_INS_CGIJ, + SYSZ_INS_CGRJ, + SYSZ_INS_CIJ, + SYSZ_INS_CLGIJ, + SYSZ_INS_CLGRJ, + SYSZ_INS_CLIJ, + SYSZ_INS_CLRJ, + SYSZ_INS_CRJ, + SYSZ_INS_BER, + SYSZ_INS_JE, + SYSZ_INS_JGE, + SYSZ_INS_LOCE, + SYSZ_INS_LOCGE, + SYSZ_INS_LOCGRE, + SYSZ_INS_LOCRE, + SYSZ_INS_STOCE, + SYSZ_INS_STOCGE, + SYSZ_INS_BHR, + SYSZ_INS_BHER, + SYSZ_INS_JHE, + SYSZ_INS_JGHE, + SYSZ_INS_LOCHE, + SYSZ_INS_LOCGHE, + SYSZ_INS_LOCGRHE, + SYSZ_INS_LOCRHE, + SYSZ_INS_STOCHE, + SYSZ_INS_STOCGHE, + SYSZ_INS_JH, + SYSZ_INS_JGH, + SYSZ_INS_LOCH, + SYSZ_INS_LOCGH, + SYSZ_INS_LOCGRH, + SYSZ_INS_LOCRH, + SYSZ_INS_STOCH, + SYSZ_INS_STOCGH, + SYSZ_INS_CGIJNLH, + SYSZ_INS_CGRJNLH, + SYSZ_INS_CIJNLH, + SYSZ_INS_CLGIJNLH, + SYSZ_INS_CLGRJNLH, + SYSZ_INS_CLIJNLH, + SYSZ_INS_CLRJNLH, + SYSZ_INS_CRJNLH, + SYSZ_INS_CGIJE, + SYSZ_INS_CGRJE, + SYSZ_INS_CIJE, + SYSZ_INS_CLGIJE, + SYSZ_INS_CLGRJE, + SYSZ_INS_CLIJE, + SYSZ_INS_CLRJE, + SYSZ_INS_CRJE, + SYSZ_INS_CGIJNLE, + SYSZ_INS_CGRJNLE, + SYSZ_INS_CIJNLE, + SYSZ_INS_CLGIJNLE, + SYSZ_INS_CLGRJNLE, + SYSZ_INS_CLIJNLE, + SYSZ_INS_CLRJNLE, + SYSZ_INS_CRJNLE, + SYSZ_INS_CGIJH, + SYSZ_INS_CGRJH, + SYSZ_INS_CIJH, + SYSZ_INS_CLGIJH, + SYSZ_INS_CLGRJH, + SYSZ_INS_CLIJH, + SYSZ_INS_CLRJH, + SYSZ_INS_CRJH, + SYSZ_INS_CGIJNL, + SYSZ_INS_CGRJNL, + SYSZ_INS_CIJNL, + SYSZ_INS_CLGIJNL, + SYSZ_INS_CLGRJNL, + SYSZ_INS_CLIJNL, + SYSZ_INS_CLRJNL, + SYSZ_INS_CRJNL, + SYSZ_INS_CGIJHE, + SYSZ_INS_CGRJHE, + SYSZ_INS_CIJHE, + SYSZ_INS_CLGIJHE, + SYSZ_INS_CLGRJHE, + SYSZ_INS_CLIJHE, + SYSZ_INS_CLRJHE, + SYSZ_INS_CRJHE, + SYSZ_INS_CGIJNHE, + SYSZ_INS_CGRJNHE, + SYSZ_INS_CIJNHE, + SYSZ_INS_CLGIJNHE, + SYSZ_INS_CLGRJNHE, + SYSZ_INS_CLIJNHE, + SYSZ_INS_CLRJNHE, + SYSZ_INS_CRJNHE, + SYSZ_INS_CGIJL, + SYSZ_INS_CGRJL, + SYSZ_INS_CIJL, + SYSZ_INS_CLGIJL, + SYSZ_INS_CLGRJL, + SYSZ_INS_CLIJL, + SYSZ_INS_CLRJL, + SYSZ_INS_CRJL, + SYSZ_INS_CGIJNH, + SYSZ_INS_CGRJNH, + SYSZ_INS_CIJNH, + SYSZ_INS_CLGIJNH, + SYSZ_INS_CLGRJNH, + SYSZ_INS_CLIJNH, + SYSZ_INS_CLRJNH, + SYSZ_INS_CRJNH, + SYSZ_INS_CGIJLE, + SYSZ_INS_CGRJLE, + SYSZ_INS_CIJLE, + SYSZ_INS_CLGIJLE, + SYSZ_INS_CLGRJLE, + SYSZ_INS_CLIJLE, + SYSZ_INS_CLRJLE, + SYSZ_INS_CRJLE, + SYSZ_INS_CGIJNE, + SYSZ_INS_CGRJNE, + SYSZ_INS_CIJNE, + SYSZ_INS_CLGIJNE, + SYSZ_INS_CLGRJNE, + SYSZ_INS_CLIJNE, + SYSZ_INS_CLRJNE, + SYSZ_INS_CRJNE, + SYSZ_INS_CGIJLH, + SYSZ_INS_CGRJLH, + SYSZ_INS_CIJLH, + SYSZ_INS_CLGIJLH, + SYSZ_INS_CLGRJLH, + SYSZ_INS_CLIJLH, + SYSZ_INS_CLRJLH, + SYSZ_INS_CRJLH, + SYSZ_INS_BLR, + SYSZ_INS_BLER, + SYSZ_INS_JLE, + SYSZ_INS_JGLE, + SYSZ_INS_LOCLE, + SYSZ_INS_LOCGLE, + SYSZ_INS_LOCGRLE, + SYSZ_INS_LOCRLE, + SYSZ_INS_STOCLE, + SYSZ_INS_STOCGLE, + SYSZ_INS_BLHR, + SYSZ_INS_JLH, + SYSZ_INS_JGLH, + SYSZ_INS_LOCLH, + SYSZ_INS_LOCGLH, + SYSZ_INS_LOCGRLH, + SYSZ_INS_LOCRLH, + SYSZ_INS_STOCLH, + SYSZ_INS_STOCGLH, + SYSZ_INS_JL, + SYSZ_INS_JGL, + SYSZ_INS_LOCL, + SYSZ_INS_LOCGL, + SYSZ_INS_LOCGRL, + SYSZ_INS_LOCRL, + SYSZ_INS_LOC, + SYSZ_INS_LOCG, + SYSZ_INS_LOCGR, + SYSZ_INS_LOCR, + SYSZ_INS_STOCL, + SYSZ_INS_STOCGL, + SYSZ_INS_BNER, + SYSZ_INS_JNE, + SYSZ_INS_JGNE, + SYSZ_INS_LOCNE, + SYSZ_INS_LOCGNE, + SYSZ_INS_LOCGRNE, + SYSZ_INS_LOCRNE, + SYSZ_INS_STOCNE, + SYSZ_INS_STOCGNE, + SYSZ_INS_BNHR, + SYSZ_INS_BNHER, + SYSZ_INS_JNHE, + SYSZ_INS_JGNHE, + SYSZ_INS_LOCNHE, + SYSZ_INS_LOCGNHE, + SYSZ_INS_LOCGRNHE, + SYSZ_INS_LOCRNHE, + SYSZ_INS_STOCNHE, + SYSZ_INS_STOCGNHE, + SYSZ_INS_JNH, + SYSZ_INS_JGNH, + SYSZ_INS_LOCNH, + SYSZ_INS_LOCGNH, + SYSZ_INS_LOCGRNH, + SYSZ_INS_LOCRNH, + SYSZ_INS_STOCNH, + SYSZ_INS_STOCGNH, + SYSZ_INS_BNLR, + SYSZ_INS_BNLER, + SYSZ_INS_JNLE, + SYSZ_INS_JGNLE, + SYSZ_INS_LOCNLE, + SYSZ_INS_LOCGNLE, + SYSZ_INS_LOCGRNLE, + SYSZ_INS_LOCRNLE, + SYSZ_INS_STOCNLE, + SYSZ_INS_STOCGNLE, + SYSZ_INS_BNLHR, + SYSZ_INS_JNLH, + SYSZ_INS_JGNLH, + SYSZ_INS_LOCNLH, + SYSZ_INS_LOCGNLH, + SYSZ_INS_LOCGRNLH, + SYSZ_INS_LOCRNLH, + SYSZ_INS_STOCNLH, + SYSZ_INS_STOCGNLH, + SYSZ_INS_JNL, + SYSZ_INS_JGNL, + SYSZ_INS_LOCNL, + SYSZ_INS_LOCGNL, + SYSZ_INS_LOCGRNL, + SYSZ_INS_LOCRNL, + SYSZ_INS_STOCNL, + SYSZ_INS_STOCGNL, + SYSZ_INS_BNOR, + SYSZ_INS_JNO, + SYSZ_INS_JGNO, + SYSZ_INS_LOCNO, + SYSZ_INS_LOCGNO, + SYSZ_INS_LOCGRNO, + SYSZ_INS_LOCRNO, + SYSZ_INS_STOCNO, + SYSZ_INS_STOCGNO, + SYSZ_INS_BOR, + SYSZ_INS_JO, + SYSZ_INS_JGO, + SYSZ_INS_LOCO, + SYSZ_INS_LOCGO, + SYSZ_INS_LOCGRO, + SYSZ_INS_LOCRO, + SYSZ_INS_STOCO, + SYSZ_INS_STOCGO, + SYSZ_INS_STOC, + SYSZ_INS_STOCG, + SYSZ_INS_BASR, + SYSZ_INS_BR, + SYSZ_INS_BRAS, + SYSZ_INS_BRASL, + SYSZ_INS_J, + SYSZ_INS_JG, + SYSZ_INS_BRCT, + SYSZ_INS_BRCTG, + SYSZ_INS_C, + SYSZ_INS_CDB, + SYSZ_INS_CDBR, + SYSZ_INS_CDFBR, + SYSZ_INS_CDGBR, + SYSZ_INS_CDLFBR, + SYSZ_INS_CDLGBR, + SYSZ_INS_CEB, + SYSZ_INS_CEBR, + SYSZ_INS_CEFBR, + SYSZ_INS_CEGBR, + SYSZ_INS_CELFBR, + SYSZ_INS_CELGBR, + SYSZ_INS_CFDBR, + SYSZ_INS_CFEBR, + SYSZ_INS_CFI, + SYSZ_INS_CFXBR, + SYSZ_INS_CG, + SYSZ_INS_CGDBR, + SYSZ_INS_CGEBR, + SYSZ_INS_CGF, + SYSZ_INS_CGFI, + SYSZ_INS_CGFR, + SYSZ_INS_CGFRL, + SYSZ_INS_CGH, + SYSZ_INS_CGHI, + SYSZ_INS_CGHRL, + SYSZ_INS_CGHSI, + SYSZ_INS_CGR, + SYSZ_INS_CGRL, + SYSZ_INS_CGXBR, + SYSZ_INS_CH, + SYSZ_INS_CHF, + SYSZ_INS_CHHSI, + SYSZ_INS_CHI, + SYSZ_INS_CHRL, + SYSZ_INS_CHSI, + SYSZ_INS_CHY, + SYSZ_INS_CIH, + SYSZ_INS_CL, + SYSZ_INS_CLC, + SYSZ_INS_CLFDBR, + SYSZ_INS_CLFEBR, + SYSZ_INS_CLFHSI, + SYSZ_INS_CLFI, + SYSZ_INS_CLFXBR, + SYSZ_INS_CLG, + SYSZ_INS_CLGDBR, + SYSZ_INS_CLGEBR, + SYSZ_INS_CLGF, + SYSZ_INS_CLGFI, + SYSZ_INS_CLGFR, + SYSZ_INS_CLGFRL, + SYSZ_INS_CLGHRL, + SYSZ_INS_CLGHSI, + SYSZ_INS_CLGR, + SYSZ_INS_CLGRL, + SYSZ_INS_CLGXBR, + SYSZ_INS_CLHF, + SYSZ_INS_CLHHSI, + SYSZ_INS_CLHRL, + SYSZ_INS_CLI, + SYSZ_INS_CLIH, + SYSZ_INS_CLIY, + SYSZ_INS_CLR, + SYSZ_INS_CLRL, + SYSZ_INS_CLST, + SYSZ_INS_CLY, + SYSZ_INS_CPSDR, + SYSZ_INS_CR, + SYSZ_INS_CRL, + SYSZ_INS_CS, + SYSZ_INS_CSG, + SYSZ_INS_CSY, + SYSZ_INS_CXBR, + SYSZ_INS_CXFBR, + SYSZ_INS_CXGBR, + SYSZ_INS_CXLFBR, + SYSZ_INS_CXLGBR, + SYSZ_INS_CY, + SYSZ_INS_DDB, + SYSZ_INS_DDBR, + SYSZ_INS_DEB, + SYSZ_INS_DEBR, + SYSZ_INS_DL, + SYSZ_INS_DLG, + SYSZ_INS_DLGR, + SYSZ_INS_DLR, + SYSZ_INS_DSG, + SYSZ_INS_DSGF, + SYSZ_INS_DSGFR, + SYSZ_INS_DSGR, + SYSZ_INS_DXBR, + SYSZ_INS_EAR, + SYSZ_INS_FIDBR, + SYSZ_INS_FIDBRA, + SYSZ_INS_FIEBR, + SYSZ_INS_FIEBRA, + SYSZ_INS_FIXBR, + SYSZ_INS_FIXBRA, + SYSZ_INS_FLOGR, + SYSZ_INS_IC, + SYSZ_INS_ICY, + SYSZ_INS_IIHF, + SYSZ_INS_IIHH, + SYSZ_INS_IIHL, + SYSZ_INS_IILF, + SYSZ_INS_IILH, + SYSZ_INS_IILL, + SYSZ_INS_IPM, + SYSZ_INS_L, + SYSZ_INS_LA, + SYSZ_INS_LAA, + SYSZ_INS_LAAG, + SYSZ_INS_LAAL, + SYSZ_INS_LAALG, + SYSZ_INS_LAN, + SYSZ_INS_LANG, + SYSZ_INS_LAO, + SYSZ_INS_LAOG, + SYSZ_INS_LARL, + SYSZ_INS_LAX, + SYSZ_INS_LAXG, + SYSZ_INS_LAY, + SYSZ_INS_LB, + SYSZ_INS_LBH, + SYSZ_INS_LBR, + SYSZ_INS_LCDBR, + SYSZ_INS_LCEBR, + SYSZ_INS_LCGFR, + SYSZ_INS_LCGR, + SYSZ_INS_LCR, + SYSZ_INS_LCXBR, + SYSZ_INS_LD, + SYSZ_INS_LDEB, + SYSZ_INS_LDEBR, + SYSZ_INS_LDGR, + SYSZ_INS_LDR, + SYSZ_INS_LDXBR, + SYSZ_INS_LDXBRA, + SYSZ_INS_LDY, + SYSZ_INS_LE, + SYSZ_INS_LEDBR, + SYSZ_INS_LEDBRA, + SYSZ_INS_LER, + SYSZ_INS_LEXBR, + SYSZ_INS_LEXBRA, + SYSZ_INS_LEY, + SYSZ_INS_LFH, + SYSZ_INS_LG, + SYSZ_INS_LGB, + SYSZ_INS_LGBR, + SYSZ_INS_LGDR, + SYSZ_INS_LGF, + SYSZ_INS_LGFI, + SYSZ_INS_LGFR, + SYSZ_INS_LGFRL, + SYSZ_INS_LGH, + SYSZ_INS_LGHI, + SYSZ_INS_LGHR, + SYSZ_INS_LGHRL, + SYSZ_INS_LGR, + SYSZ_INS_LGRL, + SYSZ_INS_LH, + SYSZ_INS_LHH, + SYSZ_INS_LHI, + SYSZ_INS_LHR, + SYSZ_INS_LHRL, + SYSZ_INS_LHY, + SYSZ_INS_LLC, + SYSZ_INS_LLCH, + SYSZ_INS_LLCR, + SYSZ_INS_LLGC, + SYSZ_INS_LLGCR, + SYSZ_INS_LLGF, + SYSZ_INS_LLGFR, + SYSZ_INS_LLGFRL, + SYSZ_INS_LLGH, + SYSZ_INS_LLGHR, + SYSZ_INS_LLGHRL, + SYSZ_INS_LLH, + SYSZ_INS_LLHH, + SYSZ_INS_LLHR, + SYSZ_INS_LLHRL, + SYSZ_INS_LLIHF, + SYSZ_INS_LLIHH, + SYSZ_INS_LLIHL, + SYSZ_INS_LLILF, + SYSZ_INS_LLILH, + SYSZ_INS_LLILL, + SYSZ_INS_LMG, + SYSZ_INS_LNDBR, + SYSZ_INS_LNEBR, + SYSZ_INS_LNGFR, + SYSZ_INS_LNGR, + SYSZ_INS_LNR, + SYSZ_INS_LNXBR, + SYSZ_INS_LPDBR, + SYSZ_INS_LPEBR, + SYSZ_INS_LPGFR, + SYSZ_INS_LPGR, + SYSZ_INS_LPR, + SYSZ_INS_LPXBR, + SYSZ_INS_LR, + SYSZ_INS_LRL, + SYSZ_INS_LRV, + SYSZ_INS_LRVG, + SYSZ_INS_LRVGR, + SYSZ_INS_LRVR, + SYSZ_INS_LT, + SYSZ_INS_LTDBR, + SYSZ_INS_LTEBR, + SYSZ_INS_LTG, + SYSZ_INS_LTGF, + SYSZ_INS_LTGFR, + SYSZ_INS_LTGR, + SYSZ_INS_LTR, + SYSZ_INS_LTXBR, + SYSZ_INS_LXDB, + SYSZ_INS_LXDBR, + SYSZ_INS_LXEB, + SYSZ_INS_LXEBR, + SYSZ_INS_LXR, + SYSZ_INS_LY, + SYSZ_INS_LZDR, + SYSZ_INS_LZER, + SYSZ_INS_LZXR, + SYSZ_INS_MADB, + SYSZ_INS_MADBR, + SYSZ_INS_MAEB, + SYSZ_INS_MAEBR, + SYSZ_INS_MDB, + SYSZ_INS_MDBR, + SYSZ_INS_MDEB, + SYSZ_INS_MDEBR, + SYSZ_INS_MEEB, + SYSZ_INS_MEEBR, + SYSZ_INS_MGHI, + SYSZ_INS_MH, + SYSZ_INS_MHI, + SYSZ_INS_MHY, + SYSZ_INS_MLG, + SYSZ_INS_MLGR, + SYSZ_INS_MS, + SYSZ_INS_MSDB, + SYSZ_INS_MSDBR, + SYSZ_INS_MSEB, + SYSZ_INS_MSEBR, + SYSZ_INS_MSFI, + SYSZ_INS_MSG, + SYSZ_INS_MSGF, + SYSZ_INS_MSGFI, + SYSZ_INS_MSGFR, + SYSZ_INS_MSGR, + SYSZ_INS_MSR, + SYSZ_INS_MSY, + SYSZ_INS_MVC, + SYSZ_INS_MVGHI, + SYSZ_INS_MVHHI, + SYSZ_INS_MVHI, + SYSZ_INS_MVI, + SYSZ_INS_MVIY, + SYSZ_INS_MVST, + SYSZ_INS_MXBR, + SYSZ_INS_MXDB, + SYSZ_INS_MXDBR, + SYSZ_INS_N, + SYSZ_INS_NC, + SYSZ_INS_NG, + SYSZ_INS_NGR, + SYSZ_INS_NGRK, + SYSZ_INS_NI, + SYSZ_INS_NIHF, + SYSZ_INS_NIHH, + SYSZ_INS_NIHL, + SYSZ_INS_NILF, + SYSZ_INS_NILH, + SYSZ_INS_NILL, + SYSZ_INS_NIY, + SYSZ_INS_NR, + SYSZ_INS_NRK, + SYSZ_INS_NY, + SYSZ_INS_O, + SYSZ_INS_OC, + SYSZ_INS_OG, + SYSZ_INS_OGR, + SYSZ_INS_OGRK, + SYSZ_INS_OI, + SYSZ_INS_OIHF, + SYSZ_INS_OIHH, + SYSZ_INS_OIHL, + SYSZ_INS_OILF, + SYSZ_INS_OILH, + SYSZ_INS_OILL, + SYSZ_INS_OIY, + SYSZ_INS_OR, + SYSZ_INS_ORK, + SYSZ_INS_OY, + SYSZ_INS_PFD, + SYSZ_INS_PFDRL, + SYSZ_INS_RISBG, + SYSZ_INS_RISBHG, + SYSZ_INS_RISBLG, + SYSZ_INS_RLL, + SYSZ_INS_RLLG, + SYSZ_INS_RNSBG, + SYSZ_INS_ROSBG, + SYSZ_INS_RXSBG, + SYSZ_INS_S, + SYSZ_INS_SDB, + SYSZ_INS_SDBR, + SYSZ_INS_SEB, + SYSZ_INS_SEBR, + SYSZ_INS_SG, + SYSZ_INS_SGF, + SYSZ_INS_SGFR, + SYSZ_INS_SGR, + SYSZ_INS_SGRK, + SYSZ_INS_SH, + SYSZ_INS_SHY, + SYSZ_INS_SL, + SYSZ_INS_SLB, + SYSZ_INS_SLBG, + SYSZ_INS_SLBR, + SYSZ_INS_SLFI, + SYSZ_INS_SLG, + SYSZ_INS_SLBGR, + SYSZ_INS_SLGF, + SYSZ_INS_SLGFI, + SYSZ_INS_SLGFR, + SYSZ_INS_SLGR, + SYSZ_INS_SLGRK, + SYSZ_INS_SLL, + SYSZ_INS_SLLG, + SYSZ_INS_SLLK, + SYSZ_INS_SLR, + SYSZ_INS_SLRK, + SYSZ_INS_SLY, + SYSZ_INS_SQDB, + SYSZ_INS_SQDBR, + SYSZ_INS_SQEB, + SYSZ_INS_SQEBR, + SYSZ_INS_SQXBR, + SYSZ_INS_SR, + SYSZ_INS_SRA, + SYSZ_INS_SRAG, + SYSZ_INS_SRAK, + SYSZ_INS_SRK, + SYSZ_INS_SRL, + SYSZ_INS_SRLG, + SYSZ_INS_SRLK, + SYSZ_INS_SRST, + SYSZ_INS_ST, + SYSZ_INS_STC, + SYSZ_INS_STCH, + SYSZ_INS_STCY, + SYSZ_INS_STD, + SYSZ_INS_STDY, + SYSZ_INS_STE, + SYSZ_INS_STEY, + SYSZ_INS_STFH, + SYSZ_INS_STG, + SYSZ_INS_STGRL, + SYSZ_INS_STH, + SYSZ_INS_STHH, + SYSZ_INS_STHRL, + SYSZ_INS_STHY, + SYSZ_INS_STMG, + SYSZ_INS_STRL, + SYSZ_INS_STRV, + SYSZ_INS_STRVG, + SYSZ_INS_STY, + SYSZ_INS_SXBR, + SYSZ_INS_SY, + SYSZ_INS_TM, + SYSZ_INS_TMHH, + SYSZ_INS_TMHL, + SYSZ_INS_TMLH, + SYSZ_INS_TMLL, + SYSZ_INS_TMY, + SYSZ_INS_X, + SYSZ_INS_XC, + SYSZ_INS_XG, + SYSZ_INS_XGR, + SYSZ_INS_XGRK, + SYSZ_INS_XI, + SYSZ_INS_XIHF, + SYSZ_INS_XILF, + SYSZ_INS_XIY, + SYSZ_INS_XR, + SYSZ_INS_XRK, + SYSZ_INS_XY, + + SYSZ_INS_ENDING, // <-- mark the end of the list of instructions +} sysz_insn; + +//> Group of SystemZ instructions +typedef enum sysz_insn_group { + SYSZ_GRP_INVALID = 0, // = CS_GRP_INVALID + + //> Generic groups + // all jump instructions (conditional+direct+indirect jumps) + SYSZ_GRP_JUMP, // = CS_GRP_JUMP + + //> Architecture-specific groups + SYSZ_GRP_DISTINCTOPS = 128, + SYSZ_GRP_FPEXTENSION, + SYSZ_GRP_HIGHWORD, + SYSZ_GRP_INTERLOCKEDACCESS1, + SYSZ_GRP_LOADSTOREONCOND, + + SYSZ_GRP_ENDING, // <-- mark the end of the list of groups +} sysz_insn_group; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/x86.h b/include/x86.h new file mode 100644 index 0000000..a2b4976 --- /dev/null +++ b/include/x86.h @@ -0,0 +1,1630 @@ +#ifndef CAPSTONE_X86_H +#define CAPSTONE_X86_H + +/* Capstone Disassembly Engine */ +/* By Nguyen Anh Quynh , 2013-2014 */ + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(_MSC_VER) || !defined(_KERNEL_MODE) +#include +#endif + +// Calculate relative address for X86-64, given cs_insn structure +#define X86_REL_ADDR(insn) (insn.address + insn.size + insn.detail->x86.disp) + +//> X86 registers +typedef enum x86_reg { + X86_REG_INVALID = 0, + X86_REG_AH, X86_REG_AL, X86_REG_AX, X86_REG_BH, X86_REG_BL, + X86_REG_BP, X86_REG_BPL, X86_REG_BX, X86_REG_CH, X86_REG_CL, + X86_REG_CS, X86_REG_CX, X86_REG_DH, X86_REG_DI, X86_REG_DIL, + X86_REG_DL, X86_REG_DS, X86_REG_DX, X86_REG_EAX, X86_REG_EBP, + X86_REG_EBX, X86_REG_ECX, X86_REG_EDI, X86_REG_EDX, X86_REG_EFLAGS, + X86_REG_EIP, X86_REG_EIZ, X86_REG_ES, X86_REG_ESI, X86_REG_ESP, + X86_REG_FPSW, X86_REG_FS, X86_REG_GS, X86_REG_IP, X86_REG_RAX, + X86_REG_RBP, X86_REG_RBX, X86_REG_RCX, X86_REG_RDI, X86_REG_RDX, + X86_REG_RIP, X86_REG_RIZ, X86_REG_RSI, X86_REG_RSP, X86_REG_SI, + X86_REG_SIL, X86_REG_SP, X86_REG_SPL, X86_REG_SS, X86_REG_CR0, + X86_REG_CR1, X86_REG_CR2, X86_REG_CR3, X86_REG_CR4, X86_REG_CR5, + X86_REG_CR6, X86_REG_CR7, X86_REG_CR8, X86_REG_CR9, X86_REG_CR10, + X86_REG_CR11, X86_REG_CR12, X86_REG_CR13, X86_REG_CR14, X86_REG_CR15, + X86_REG_DR0, X86_REG_DR1, X86_REG_DR2, X86_REG_DR3, X86_REG_DR4, + X86_REG_DR5, X86_REG_DR6, X86_REG_DR7, X86_REG_FP0, X86_REG_FP1, + X86_REG_FP2, X86_REG_FP3, X86_REG_FP4, X86_REG_FP5, X86_REG_FP6, X86_REG_FP7, + X86_REG_K0, X86_REG_K1, X86_REG_K2, X86_REG_K3, X86_REG_K4, + X86_REG_K5, X86_REG_K6, X86_REG_K7, X86_REG_MM0, X86_REG_MM1, + X86_REG_MM2, X86_REG_MM3, X86_REG_MM4, X86_REG_MM5, X86_REG_MM6, + X86_REG_MM7, X86_REG_R8, X86_REG_R9, X86_REG_R10, X86_REG_R11, + X86_REG_R12, X86_REG_R13, X86_REG_R14, X86_REG_R15, + X86_REG_ST0, X86_REG_ST1, X86_REG_ST2, X86_REG_ST3, + X86_REG_ST4, X86_REG_ST5, X86_REG_ST6, X86_REG_ST7, + X86_REG_XMM0, X86_REG_XMM1, X86_REG_XMM2, X86_REG_XMM3, X86_REG_XMM4, + X86_REG_XMM5, X86_REG_XMM6, X86_REG_XMM7, X86_REG_XMM8, X86_REG_XMM9, + X86_REG_XMM10, X86_REG_XMM11, X86_REG_XMM12, X86_REG_XMM13, X86_REG_XMM14, + X86_REG_XMM15, X86_REG_XMM16, X86_REG_XMM17, X86_REG_XMM18, X86_REG_XMM19, + X86_REG_XMM20, X86_REG_XMM21, X86_REG_XMM22, X86_REG_XMM23, X86_REG_XMM24, + X86_REG_XMM25, X86_REG_XMM26, X86_REG_XMM27, X86_REG_XMM28, X86_REG_XMM29, + X86_REG_XMM30, X86_REG_XMM31, X86_REG_YMM0, X86_REG_YMM1, X86_REG_YMM2, + X86_REG_YMM3, X86_REG_YMM4, X86_REG_YMM5, X86_REG_YMM6, X86_REG_YMM7, + X86_REG_YMM8, X86_REG_YMM9, X86_REG_YMM10, X86_REG_YMM11, X86_REG_YMM12, + X86_REG_YMM13, X86_REG_YMM14, X86_REG_YMM15, X86_REG_YMM16, X86_REG_YMM17, + X86_REG_YMM18, X86_REG_YMM19, X86_REG_YMM20, X86_REG_YMM21, X86_REG_YMM22, + X86_REG_YMM23, X86_REG_YMM24, X86_REG_YMM25, X86_REG_YMM26, X86_REG_YMM27, + X86_REG_YMM28, X86_REG_YMM29, X86_REG_YMM30, X86_REG_YMM31, X86_REG_ZMM0, + X86_REG_ZMM1, X86_REG_ZMM2, X86_REG_ZMM3, X86_REG_ZMM4, X86_REG_ZMM5, + X86_REG_ZMM6, X86_REG_ZMM7, X86_REG_ZMM8, X86_REG_ZMM9, X86_REG_ZMM10, + X86_REG_ZMM11, X86_REG_ZMM12, X86_REG_ZMM13, X86_REG_ZMM14, X86_REG_ZMM15, + X86_REG_ZMM16, X86_REG_ZMM17, X86_REG_ZMM18, X86_REG_ZMM19, X86_REG_ZMM20, + X86_REG_ZMM21, X86_REG_ZMM22, X86_REG_ZMM23, X86_REG_ZMM24, X86_REG_ZMM25, + X86_REG_ZMM26, X86_REG_ZMM27, X86_REG_ZMM28, X86_REG_ZMM29, X86_REG_ZMM30, + X86_REG_ZMM31, X86_REG_R8B, X86_REG_R9B, X86_REG_R10B, X86_REG_R11B, + X86_REG_R12B, X86_REG_R13B, X86_REG_R14B, X86_REG_R15B, X86_REG_R8D, + X86_REG_R9D, X86_REG_R10D, X86_REG_R11D, X86_REG_R12D, X86_REG_R13D, + X86_REG_R14D, X86_REG_R15D, X86_REG_R8W, X86_REG_R9W, X86_REG_R10W, + X86_REG_R11W, X86_REG_R12W, X86_REG_R13W, X86_REG_R14W, X86_REG_R15W, + + X86_REG_ENDING // <-- mark the end of the list of registers +} x86_reg; + +//> Operand type for instruction's operands +typedef enum x86_op_type { + X86_OP_INVALID = 0, // = CS_OP_INVALID (Uninitialized). + X86_OP_REG, // = CS_OP_REG (Register operand). + X86_OP_IMM, // = CS_OP_IMM (Immediate operand). + X86_OP_MEM, // = CS_OP_MEM (Memory operand). + X86_OP_FP, // = CS_OP_FP (Floating-Point operand). +} x86_op_type; + +//> AVX broadcast type +typedef enum x86_avx_bcast { + X86_AVX_BCAST_INVALID = 0, // Uninitialized. + X86_AVX_BCAST_2, // AVX512 broadcast type {1to2} + X86_AVX_BCAST_4, // AVX512 broadcast type {1to4} + X86_AVX_BCAST_8, // AVX512 broadcast type {1to8} + X86_AVX_BCAST_16, // AVX512 broadcast type {1to16} +} x86_avx_bcast; + +//> SSE Code Condition type +typedef enum x86_sse_cc { + X86_SSE_CC_INVALID = 0, // Uninitialized. + X86_SSE_CC_EQ, + X86_SSE_CC_LT, + X86_SSE_CC_LE, + X86_SSE_CC_UNORD, + X86_SSE_CC_NEQ, + X86_SSE_CC_NLT, + X86_SSE_CC_NLE, + X86_SSE_CC_ORD, + X86_SSE_CC_EQ_UQ, + X86_SSE_CC_NGE, + X86_SSE_CC_NGT, + X86_SSE_CC_FALSE, + X86_SSE_CC_NEQ_OQ, + X86_SSE_CC_GE, + X86_SSE_CC_GT, + X86_SSE_CC_TRUE, +} x86_sse_cc; + +//> AVX Code Condition type +typedef enum x86_avx_cc { + X86_AVX_CC_INVALID = 0, // Uninitialized. + X86_AVX_CC_EQ, + X86_AVX_CC_LT, + X86_AVX_CC_LE, + X86_AVX_CC_UNORD, + X86_AVX_CC_NEQ, + X86_AVX_CC_NLT, + X86_AVX_CC_NLE, + X86_AVX_CC_ORD, + X86_AVX_CC_EQ_UQ, + X86_AVX_CC_NGE, + X86_AVX_CC_NGT, + X86_AVX_CC_FALSE, + X86_AVX_CC_NEQ_OQ, + X86_AVX_CC_GE, + X86_AVX_CC_GT, + X86_AVX_CC_TRUE, + X86_AVX_CC_EQ_OS, + X86_AVX_CC_LT_OQ, + X86_AVX_CC_LE_OQ, + X86_AVX_CC_UNORD_S, + X86_AVX_CC_NEQ_US, + X86_AVX_CC_NLT_UQ, + X86_AVX_CC_NLE_UQ, + X86_AVX_CC_ORD_S, + X86_AVX_CC_EQ_US, + X86_AVX_CC_NGE_UQ, + X86_AVX_CC_NGT_UQ, + X86_AVX_CC_FALSE_OS, + X86_AVX_CC_NEQ_OS, + X86_AVX_CC_GE_OQ, + X86_AVX_CC_GT_OQ, + X86_AVX_CC_TRUE_US, +} x86_avx_cc; + +//> AVX static rounding mode type +typedef enum x86_avx_rm { + X86_AVX_RM_INVALID = 0, // Uninitialized. + X86_AVX_RM_RN, // Round to nearest + X86_AVX_RM_RD, // Round down + X86_AVX_RM_RU, // Round up + X86_AVX_RM_RZ, // Round toward zero +} x86_avx_rm; + +//> Instruction prefixes - to be used in cs_x86.prefix[] +typedef enum x86_prefix { + X86_PREFIX_LOCK = 0xf0, // lock (cs_x86.prefix[0] + X86_PREFIX_REP = 0xf3, // rep (cs_x86.prefix[0] + X86_PREFIX_REPNE = 0xf2, // repne (cs_x86.prefix[0] + + X86_PREFIX_CS = 0x2e, // segment override CS (cs_x86.prefix[1] + X86_PREFIX_SS = 0x36, // segment override SS (cs_x86.prefix[1] + X86_PREFIX_DS = 0x3e, // segment override DS (cs_x86.prefix[1] + X86_PREFIX_ES = 0x26, // segment override ES (cs_x86.prefix[1] + X86_PREFIX_FS = 0x64, // segment override FS (cs_x86.prefix[1] + X86_PREFIX_GS = 0x65, // segment override GS (cs_x86.prefix[1] + + X86_PREFIX_OPSIZE = 0x66, // operand-size override (cs_x86.prefix[2] + X86_PREFIX_ADDRSIZE = 0x67, // address-size override (cs_x86.prefix[3] +} x86_prefix; + +// Instruction's operand referring to memory +// This is associated with X86_OP_MEM operand type above +typedef struct x86_op_mem { + unsigned int segment; // segment register (or X86_REG_INVALID if irrelevant) + unsigned int base; // base register (or X86_REG_INVALID if irrelevant) + unsigned int index; // index register (or X86_REG_INVALID if irrelevant) + int scale; // scale for index register + int64_t disp; // displacement value +} x86_op_mem; + +// Instruction operand +typedef struct cs_x86_op { + x86_op_type type; // operand type + union { + x86_reg reg; // register value for REG operand + int64_t imm; // immediate value for IMM operand + double fp; // floating point value for FP operand + x86_op_mem mem; // base/index/scale/disp value for MEM operand + }; + + // size of this operand (in bytes). + uint8_t size; + + // AVX broadcast type, or 0 if irrelevant + x86_avx_bcast avx_bcast; + + // AVX zero opmask {z} + bool avx_zero_opmask; +} cs_x86_op; + +// Instruction structure +typedef struct cs_x86 { + // Instruction prefix, which can be up to 4 bytes. + // A prefix byte gets value 0 when irrelevant. + // prefix[0] indicates REP/REPNE/LOCK prefix (See X86_PREFIX_REP/REPNE/LOCK above) + // prefix[1] indicates segment override (irrelevant for x86_64): + // See X86_PREFIX_CS/SS/DS/ES/FS/GS above. + // prefix[2] indicates operand-size override (X86_PREFIX_OPSIZE) + // prefix[3] indicates address-size override (X86_PREFIX_ADDRSIZE) + uint8_t prefix[4]; + + // Instruction opcode, wich can be from 1 to 4 bytes in size. + // This contains VEX opcode as well. + // An trailing opcode byte gets value 0 when irrelevant. + uint8_t opcode[4]; + + // REX prefix: only a non-zero value is relavant for x86_64 + uint8_t rex; + + // Address size, which can be overrided with above prefix[5]. + uint8_t addr_size; + + // ModR/M byte + uint8_t modrm; + + // SIB value, or 0 when irrelevant. + uint8_t sib; + + // Displacement value, or 0 when irrelevant. + int32_t disp; + + /* SIB state */ + // SIB index register, or X86_REG_INVALID when irrelevant. + x86_reg sib_index; + // SIB scale. only applicable if sib_index is relavant. + int8_t sib_scale; + // SIB base register, or X86_REG_INVALID when irrelevant. + x86_reg sib_base; + + // SSE Code Condition + x86_sse_cc sse_cc; + + // AVX Code Condition + x86_avx_cc avx_cc; + + // AVX Suppress all Exception + bool avx_sae; + + // AVX static rounding mode + x86_avx_rm avx_rm; + + // Number of operands of this instruction, + // or 0 when instruction has no operand. + uint8_t op_count; + + cs_x86_op operands[8]; // operands for this instruction. +} cs_x86; + +//> X86 instructions +typedef enum x86_insn { + X86_INS_INVALID = 0, + + X86_INS_AAA, + X86_INS_AAD, + X86_INS_AAM, + X86_INS_AAS, + X86_INS_FABS, + X86_INS_ADC, + X86_INS_ADCX, + X86_INS_ADD, + X86_INS_ADDPD, + X86_INS_ADDPS, + X86_INS_ADDSD, + X86_INS_ADDSS, + X86_INS_ADDSUBPD, + X86_INS_ADDSUBPS, + X86_INS_FADD, + X86_INS_FIADD, + X86_INS_FADDP, + X86_INS_ADOX, + X86_INS_AESDECLAST, + X86_INS_AESDEC, + X86_INS_AESENCLAST, + X86_INS_AESENC, + X86_INS_AESIMC, + X86_INS_AESKEYGENASSIST, + X86_INS_AND, + X86_INS_ANDN, + X86_INS_ANDNPD, + X86_INS_ANDNPS, + X86_INS_ANDPD, + X86_INS_ANDPS, + X86_INS_ARPL, + X86_INS_BEXTR, + X86_INS_BLCFILL, + X86_INS_BLCI, + X86_INS_BLCIC, + X86_INS_BLCMSK, + X86_INS_BLCS, + X86_INS_BLENDPD, + X86_INS_BLENDPS, + X86_INS_BLENDVPD, + X86_INS_BLENDVPS, + X86_INS_BLSFILL, + X86_INS_BLSI, + X86_INS_BLSIC, + X86_INS_BLSMSK, + X86_INS_BLSR, + X86_INS_BOUND, + X86_INS_BSF, + X86_INS_BSR, + X86_INS_BSWAP, + X86_INS_BT, + X86_INS_BTC, + X86_INS_BTR, + X86_INS_BTS, + X86_INS_BZHI, + X86_INS_CALL, + X86_INS_CBW, + X86_INS_CDQ, + X86_INS_CDQE, + X86_INS_FCHS, + X86_INS_CLAC, + X86_INS_CLC, + X86_INS_CLD, + X86_INS_CLFLUSH, + X86_INS_CLGI, + X86_INS_CLI, + X86_INS_CLTS, + X86_INS_CMC, + X86_INS_CMOVA, + X86_INS_CMOVAE, + X86_INS_CMOVB, + X86_INS_CMOVBE, + X86_INS_FCMOVBE, + X86_INS_FCMOVB, + X86_INS_CMOVE, + X86_INS_FCMOVE, + X86_INS_CMOVG, + X86_INS_CMOVGE, + X86_INS_CMOVL, + X86_INS_CMOVLE, + X86_INS_FCMOVNBE, + X86_INS_FCMOVNB, + X86_INS_CMOVNE, + X86_INS_FCMOVNE, + X86_INS_CMOVNO, + X86_INS_CMOVNP, + X86_INS_FCMOVNU, + X86_INS_CMOVNS, + X86_INS_CMOVO, + X86_INS_CMOVP, + X86_INS_FCMOVU, + X86_INS_CMOVS, + X86_INS_CMP, + X86_INS_CMPPD, + X86_INS_CMPPS, + X86_INS_CMPSB, + X86_INS_CMPSD, + X86_INS_CMPSQ, + X86_INS_CMPSS, + X86_INS_CMPSW, + X86_INS_CMPXCHG16B, + X86_INS_CMPXCHG, + X86_INS_CMPXCHG8B, + X86_INS_COMISD, + X86_INS_COMISS, + X86_INS_FCOMP, + X86_INS_FCOMPI, + X86_INS_FCOMI, + X86_INS_FCOM, + X86_INS_FCOS, + X86_INS_CPUID, + X86_INS_CQO, + X86_INS_CRC32, + X86_INS_CVTDQ2PD, + X86_INS_CVTDQ2PS, + X86_INS_CVTPD2DQ, + X86_INS_CVTPD2PS, + X86_INS_CVTPS2DQ, + X86_INS_CVTPS2PD, + X86_INS_CVTSD2SI, + X86_INS_CVTSD2SS, + X86_INS_CVTSI2SD, + X86_INS_CVTSI2SS, + X86_INS_CVTSS2SD, + X86_INS_CVTSS2SI, + X86_INS_CVTTPD2DQ, + X86_INS_CVTTPS2DQ, + X86_INS_CVTTSD2SI, + X86_INS_CVTTSS2SI, + X86_INS_CWD, + X86_INS_CWDE, + X86_INS_DAA, + X86_INS_DAS, + X86_INS_DATA16, + X86_INS_DEC, + X86_INS_DIV, + X86_INS_DIVPD, + X86_INS_DIVPS, + X86_INS_FDIVR, + X86_INS_FIDIVR, + X86_INS_FDIVRP, + X86_INS_DIVSD, + X86_INS_DIVSS, + X86_INS_FDIV, + X86_INS_FIDIV, + X86_INS_FDIVP, + X86_INS_DPPD, + X86_INS_DPPS, + X86_INS_RET, + X86_INS_ENCLS, + X86_INS_ENCLU, + X86_INS_ENTER, + X86_INS_EXTRACTPS, + X86_INS_EXTRQ, + X86_INS_F2XM1, + X86_INS_LCALL, + X86_INS_LJMP, + X86_INS_FBLD, + X86_INS_FBSTP, + X86_INS_FCOMPP, + X86_INS_FDECSTP, + X86_INS_FEMMS, + X86_INS_FFREE, + X86_INS_FICOM, + X86_INS_FICOMP, + X86_INS_FINCSTP, + X86_INS_FLDCW, + X86_INS_FLDENV, + X86_INS_FLDL2E, + X86_INS_FLDL2T, + X86_INS_FLDLG2, + X86_INS_FLDLN2, + X86_INS_FLDPI, + X86_INS_FNCLEX, + X86_INS_FNINIT, + X86_INS_FNOP, + X86_INS_FNSTCW, + X86_INS_FNSTSW, + X86_INS_FPATAN, + X86_INS_FPREM, + X86_INS_FPREM1, + X86_INS_FPTAN, + X86_INS_FRNDINT, + X86_INS_FRSTOR, + X86_INS_FNSAVE, + X86_INS_FSCALE, + X86_INS_FSETPM, + X86_INS_FSINCOS, + X86_INS_FNSTENV, + X86_INS_FXAM, + X86_INS_FXRSTOR, + X86_INS_FXRSTOR64, + X86_INS_FXSAVE, + X86_INS_FXSAVE64, + X86_INS_FXTRACT, + X86_INS_FYL2X, + X86_INS_FYL2XP1, + X86_INS_MOVAPD, + X86_INS_MOVAPS, + X86_INS_ORPD, + X86_INS_ORPS, + X86_INS_VMOVAPD, + X86_INS_VMOVAPS, + X86_INS_XORPD, + X86_INS_XORPS, + X86_INS_GETSEC, + X86_INS_HADDPD, + X86_INS_HADDPS, + X86_INS_HLT, + X86_INS_HSUBPD, + X86_INS_HSUBPS, + X86_INS_IDIV, + X86_INS_FILD, + X86_INS_IMUL, + X86_INS_IN, + X86_INS_INC, + X86_INS_INSB, + X86_INS_INSERTPS, + X86_INS_INSERTQ, + X86_INS_INSD, + X86_INS_INSW, + X86_INS_INT, + X86_INS_INT1, + X86_INS_INT3, + X86_INS_INTO, + X86_INS_INVD, + X86_INS_INVEPT, + X86_INS_INVLPG, + X86_INS_INVLPGA, + X86_INS_INVPCID, + X86_INS_INVVPID, + X86_INS_IRET, + X86_INS_IRETD, + X86_INS_IRETQ, + X86_INS_FISTTP, + X86_INS_FIST, + X86_INS_FISTP, + X86_INS_UCOMISD, + X86_INS_UCOMISS, + X86_INS_VCMP, + X86_INS_VCOMISD, + X86_INS_VCOMISS, + X86_INS_VCVTSD2SS, + X86_INS_VCVTSI2SD, + X86_INS_VCVTSI2SS, + X86_INS_VCVTSS2SD, + X86_INS_VCVTTSD2SI, + X86_INS_VCVTTSD2USI, + X86_INS_VCVTTSS2SI, + X86_INS_VCVTTSS2USI, + X86_INS_VCVTUSI2SD, + X86_INS_VCVTUSI2SS, + X86_INS_VUCOMISD, + X86_INS_VUCOMISS, + X86_INS_JAE, + X86_INS_JA, + X86_INS_JBE, + X86_INS_JB, + X86_INS_JCXZ, + X86_INS_JECXZ, + X86_INS_JE, + X86_INS_JGE, + X86_INS_JG, + X86_INS_JLE, + X86_INS_JL, + X86_INS_JMP, + X86_INS_JNE, + X86_INS_JNO, + X86_INS_JNP, + X86_INS_JNS, + X86_INS_JO, + X86_INS_JP, + X86_INS_JRCXZ, + X86_INS_JS, + X86_INS_KANDB, + X86_INS_KANDD, + X86_INS_KANDNB, + X86_INS_KANDND, + X86_INS_KANDNQ, + X86_INS_KANDNW, + X86_INS_KANDQ, + X86_INS_KANDW, + X86_INS_KMOVB, + X86_INS_KMOVD, + X86_INS_KMOVQ, + X86_INS_KMOVW, + X86_INS_KNOTB, + X86_INS_KNOTD, + X86_INS_KNOTQ, + X86_INS_KNOTW, + X86_INS_KORB, + X86_INS_KORD, + X86_INS_KORQ, + X86_INS_KORTESTW, + X86_INS_KORW, + X86_INS_KSHIFTLW, + X86_INS_KSHIFTRW, + X86_INS_KUNPCKBW, + X86_INS_KXNORB, + X86_INS_KXNORD, + X86_INS_KXNORQ, + X86_INS_KXNORW, + X86_INS_KXORB, + X86_INS_KXORD, + X86_INS_KXORQ, + X86_INS_KXORW, + X86_INS_LAHF, + X86_INS_LAR, + X86_INS_LDDQU, + X86_INS_LDMXCSR, + X86_INS_LDS, + X86_INS_FLDZ, + X86_INS_FLD1, + X86_INS_FLD, + X86_INS_LEA, + X86_INS_LEAVE, + X86_INS_LES, + X86_INS_LFENCE, + X86_INS_LFS, + X86_INS_LGDT, + X86_INS_LGS, + X86_INS_LIDT, + X86_INS_LLDT, + X86_INS_LMSW, + X86_INS_OR, + X86_INS_SUB, + X86_INS_XOR, + X86_INS_LODSB, + X86_INS_LODSD, + X86_INS_LODSQ, + X86_INS_LODSW, + X86_INS_LOOP, + X86_INS_LOOPE, + X86_INS_LOOPNE, + X86_INS_RETF, + X86_INS_RETFQ, + X86_INS_LSL, + X86_INS_LSS, + X86_INS_LTR, + X86_INS_XADD, + X86_INS_LZCNT, + X86_INS_MASKMOVDQU, + X86_INS_MAXPD, + X86_INS_MAXPS, + X86_INS_MAXSD, + X86_INS_MAXSS, + X86_INS_MFENCE, + X86_INS_MINPD, + X86_INS_MINPS, + X86_INS_MINSD, + X86_INS_MINSS, + X86_INS_CVTPD2PI, + X86_INS_CVTPI2PD, + X86_INS_CVTPI2PS, + X86_INS_CVTPS2PI, + X86_INS_CVTTPD2PI, + X86_INS_CVTTPS2PI, + X86_INS_EMMS, + X86_INS_MASKMOVQ, + X86_INS_MOVD, + X86_INS_MOVDQ2Q, + X86_INS_MOVNTQ, + X86_INS_MOVQ2DQ, + X86_INS_MOVQ, + X86_INS_PABSB, + X86_INS_PABSD, + X86_INS_PABSW, + X86_INS_PACKSSDW, + X86_INS_PACKSSWB, + X86_INS_PACKUSWB, + X86_INS_PADDB, + X86_INS_PADDD, + X86_INS_PADDQ, + X86_INS_PADDSB, + X86_INS_PADDSW, + X86_INS_PADDUSB, + X86_INS_PADDUSW, + X86_INS_PADDW, + X86_INS_PALIGNR, + X86_INS_PANDN, + X86_INS_PAND, + X86_INS_PAVGB, + X86_INS_PAVGW, + X86_INS_PCMPEQB, + X86_INS_PCMPEQD, + X86_INS_PCMPEQW, + X86_INS_PCMPGTB, + X86_INS_PCMPGTD, + X86_INS_PCMPGTW, + X86_INS_PEXTRW, + X86_INS_PHADDSW, + X86_INS_PHADDW, + X86_INS_PHADDD, + X86_INS_PHSUBD, + X86_INS_PHSUBSW, + X86_INS_PHSUBW, + X86_INS_PINSRW, + X86_INS_PMADDUBSW, + X86_INS_PMADDWD, + X86_INS_PMAXSW, + X86_INS_PMAXUB, + X86_INS_PMINSW, + X86_INS_PMINUB, + X86_INS_PMOVMSKB, + X86_INS_PMULHRSW, + X86_INS_PMULHUW, + X86_INS_PMULHW, + X86_INS_PMULLW, + X86_INS_PMULUDQ, + X86_INS_POR, + X86_INS_PSADBW, + X86_INS_PSHUFB, + X86_INS_PSHUFW, + X86_INS_PSIGNB, + X86_INS_PSIGND, + X86_INS_PSIGNW, + X86_INS_PSLLD, + X86_INS_PSLLQ, + X86_INS_PSLLW, + X86_INS_PSRAD, + X86_INS_PSRAW, + X86_INS_PSRLD, + X86_INS_PSRLQ, + X86_INS_PSRLW, + X86_INS_PSUBB, + X86_INS_PSUBD, + X86_INS_PSUBQ, + X86_INS_PSUBSB, + X86_INS_PSUBSW, + X86_INS_PSUBUSB, + X86_INS_PSUBUSW, + X86_INS_PSUBW, + X86_INS_PUNPCKHBW, + X86_INS_PUNPCKHDQ, + X86_INS_PUNPCKHWD, + X86_INS_PUNPCKLBW, + X86_INS_PUNPCKLDQ, + X86_INS_PUNPCKLWD, + X86_INS_PXOR, + X86_INS_MONITOR, + X86_INS_MONTMUL, + X86_INS_MOV, + X86_INS_MOVABS, + X86_INS_MOVBE, + X86_INS_MOVDDUP, + X86_INS_MOVDQA, + X86_INS_MOVDQU, + X86_INS_MOVHLPS, + X86_INS_MOVHPD, + X86_INS_MOVHPS, + X86_INS_MOVLHPS, + X86_INS_MOVLPD, + X86_INS_MOVLPS, + X86_INS_MOVMSKPD, + X86_INS_MOVMSKPS, + X86_INS_MOVNTDQA, + X86_INS_MOVNTDQ, + X86_INS_MOVNTI, + X86_INS_MOVNTPD, + X86_INS_MOVNTPS, + X86_INS_MOVNTSD, + X86_INS_MOVNTSS, + X86_INS_MOVSB, + X86_INS_MOVSD, + X86_INS_MOVSHDUP, + X86_INS_MOVSLDUP, + X86_INS_MOVSQ, + X86_INS_MOVSS, + X86_INS_MOVSW, + X86_INS_MOVSX, + X86_INS_MOVSXD, + X86_INS_MOVUPD, + X86_INS_MOVUPS, + X86_INS_MOVZX, + X86_INS_MPSADBW, + X86_INS_MUL, + X86_INS_MULPD, + X86_INS_MULPS, + X86_INS_MULSD, + X86_INS_MULSS, + X86_INS_MULX, + X86_INS_FMUL, + X86_INS_FIMUL, + X86_INS_FMULP, + X86_INS_MWAIT, + X86_INS_NEG, + X86_INS_NOP, + X86_INS_NOT, + X86_INS_OUT, + X86_INS_OUTSB, + X86_INS_OUTSD, + X86_INS_OUTSW, + X86_INS_PACKUSDW, + X86_INS_PAUSE, + X86_INS_PAVGUSB, + X86_INS_PBLENDVB, + X86_INS_PBLENDW, + X86_INS_PCLMULQDQ, + X86_INS_PCMPEQQ, + X86_INS_PCMPESTRI, + X86_INS_PCMPESTRM, + X86_INS_PCMPGTQ, + X86_INS_PCMPISTRI, + X86_INS_PCMPISTRM, + X86_INS_PDEP, + X86_INS_PEXT, + X86_INS_PEXTRB, + X86_INS_PEXTRD, + X86_INS_PEXTRQ, + X86_INS_PF2ID, + X86_INS_PF2IW, + X86_INS_PFACC, + X86_INS_PFADD, + X86_INS_PFCMPEQ, + X86_INS_PFCMPGE, + X86_INS_PFCMPGT, + X86_INS_PFMAX, + X86_INS_PFMIN, + X86_INS_PFMUL, + X86_INS_PFNACC, + X86_INS_PFPNACC, + X86_INS_PFRCPIT1, + X86_INS_PFRCPIT2, + X86_INS_PFRCP, + X86_INS_PFRSQIT1, + X86_INS_PFRSQRT, + X86_INS_PFSUBR, + X86_INS_PFSUB, + X86_INS_PHMINPOSUW, + X86_INS_PI2FD, + X86_INS_PI2FW, + X86_INS_PINSRB, + X86_INS_PINSRD, + X86_INS_PINSRQ, + X86_INS_PMAXSB, + X86_INS_PMAXSD, + X86_INS_PMAXUD, + X86_INS_PMAXUW, + X86_INS_PMINSB, + X86_INS_PMINSD, + X86_INS_PMINUD, + X86_INS_PMINUW, + X86_INS_PMOVSXBD, + X86_INS_PMOVSXBQ, + X86_INS_PMOVSXBW, + X86_INS_PMOVSXDQ, + X86_INS_PMOVSXWD, + X86_INS_PMOVSXWQ, + X86_INS_PMOVZXBD, + X86_INS_PMOVZXBQ, + X86_INS_PMOVZXBW, + X86_INS_PMOVZXDQ, + X86_INS_PMOVZXWD, + X86_INS_PMOVZXWQ, + X86_INS_PMULDQ, + X86_INS_PMULHRW, + X86_INS_PMULLD, + X86_INS_POP, + X86_INS_POPAW, + X86_INS_POPAL, + X86_INS_POPCNT, + X86_INS_POPF, + X86_INS_POPFD, + X86_INS_POPFQ, + X86_INS_PREFETCH, + X86_INS_PREFETCHNTA, + X86_INS_PREFETCHT0, + X86_INS_PREFETCHT1, + X86_INS_PREFETCHT2, + X86_INS_PREFETCHW, + X86_INS_PSHUFD, + X86_INS_PSHUFHW, + X86_INS_PSHUFLW, + X86_INS_PSLLDQ, + X86_INS_PSRLDQ, + X86_INS_PSWAPD, + X86_INS_PTEST, + X86_INS_PUNPCKHQDQ, + X86_INS_PUNPCKLQDQ, + X86_INS_PUSH, + X86_INS_PUSHAW, + X86_INS_PUSHAL, + X86_INS_PUSHF, + X86_INS_PUSHFD, + X86_INS_PUSHFQ, + X86_INS_RCL, + X86_INS_RCPPS, + X86_INS_RCPSS, + X86_INS_RCR, + X86_INS_RDFSBASE, + X86_INS_RDGSBASE, + X86_INS_RDMSR, + X86_INS_RDPMC, + X86_INS_RDRAND, + X86_INS_RDSEED, + X86_INS_RDTSC, + X86_INS_RDTSCP, + X86_INS_ROL, + X86_INS_ROR, + X86_INS_RORX, + X86_INS_ROUNDPD, + X86_INS_ROUNDPS, + X86_INS_ROUNDSD, + X86_INS_ROUNDSS, + X86_INS_RSM, + X86_INS_RSQRTPS, + X86_INS_RSQRTSS, + X86_INS_SAHF, + X86_INS_SAL, + X86_INS_SALC, + X86_INS_SAR, + X86_INS_SARX, + X86_INS_SBB, + X86_INS_SCASB, + X86_INS_SCASD, + X86_INS_SCASQ, + X86_INS_SCASW, + X86_INS_SETAE, + X86_INS_SETA, + X86_INS_SETBE, + X86_INS_SETB, + X86_INS_SETE, + X86_INS_SETGE, + X86_INS_SETG, + X86_INS_SETLE, + X86_INS_SETL, + X86_INS_SETNE, + X86_INS_SETNO, + X86_INS_SETNP, + X86_INS_SETNS, + X86_INS_SETO, + X86_INS_SETP, + X86_INS_SETS, + X86_INS_SFENCE, + X86_INS_SGDT, + X86_INS_SHA1MSG1, + X86_INS_SHA1MSG2, + X86_INS_SHA1NEXTE, + X86_INS_SHA1RNDS4, + X86_INS_SHA256MSG1, + X86_INS_SHA256MSG2, + X86_INS_SHA256RNDS2, + X86_INS_SHL, + X86_INS_SHLD, + X86_INS_SHLX, + X86_INS_SHR, + X86_INS_SHRD, + X86_INS_SHRX, + X86_INS_SHUFPD, + X86_INS_SHUFPS, + X86_INS_SIDT, + X86_INS_FSIN, + X86_INS_SKINIT, + X86_INS_SLDT, + X86_INS_SMSW, + X86_INS_SQRTPD, + X86_INS_SQRTPS, + X86_INS_SQRTSD, + X86_INS_SQRTSS, + X86_INS_FSQRT, + X86_INS_STAC, + X86_INS_STC, + X86_INS_STD, + X86_INS_STGI, + X86_INS_STI, + X86_INS_STMXCSR, + X86_INS_STOSB, + X86_INS_STOSD, + X86_INS_STOSQ, + X86_INS_STOSW, + X86_INS_STR, + X86_INS_FST, + X86_INS_FSTP, + X86_INS_FSTPNCE, + X86_INS_SUBPD, + X86_INS_SUBPS, + X86_INS_FSUBR, + X86_INS_FISUBR, + X86_INS_FSUBRP, + X86_INS_SUBSD, + X86_INS_SUBSS, + X86_INS_FSUB, + X86_INS_FISUB, + X86_INS_FSUBP, + X86_INS_SWAPGS, + X86_INS_SYSCALL, + X86_INS_SYSENTER, + X86_INS_SYSEXIT, + X86_INS_SYSRET, + X86_INS_T1MSKC, + X86_INS_TEST, + X86_INS_UD2, + X86_INS_FTST, + X86_INS_TZCNT, + X86_INS_TZMSK, + X86_INS_FUCOMPI, + X86_INS_FUCOMI, + X86_INS_FUCOMPP, + X86_INS_FUCOMP, + X86_INS_FUCOM, + X86_INS_UD2B, + X86_INS_UNPCKHPD, + X86_INS_UNPCKHPS, + X86_INS_UNPCKLPD, + X86_INS_UNPCKLPS, + X86_INS_VADDPD, + X86_INS_VADDPS, + X86_INS_VADDSD, + X86_INS_VADDSS, + X86_INS_VADDSUBPD, + X86_INS_VADDSUBPS, + X86_INS_VAESDECLAST, + X86_INS_VAESDEC, + X86_INS_VAESENCLAST, + X86_INS_VAESENC, + X86_INS_VAESIMC, + X86_INS_VAESKEYGENASSIST, + X86_INS_VALIGND, + X86_INS_VALIGNQ, + X86_INS_VANDNPD, + X86_INS_VANDNPS, + X86_INS_VANDPD, + X86_INS_VANDPS, + X86_INS_VBLENDMPD, + X86_INS_VBLENDMPS, + X86_INS_VBLENDPD, + X86_INS_VBLENDPS, + X86_INS_VBLENDVPD, + X86_INS_VBLENDVPS, + X86_INS_VBROADCASTF128, + X86_INS_VBROADCASTI128, + X86_INS_VBROADCASTI32X4, + X86_INS_VBROADCASTI64X4, + X86_INS_VBROADCASTSD, + X86_INS_VBROADCASTSS, + X86_INS_VCMPPD, + X86_INS_VCMPPS, + X86_INS_VCMPSD, + X86_INS_VCMPSS, + X86_INS_VCVTDQ2PD, + X86_INS_VCVTDQ2PS, + X86_INS_VCVTPD2DQX, + X86_INS_VCVTPD2DQ, + X86_INS_VCVTPD2PSX, + X86_INS_VCVTPD2PS, + X86_INS_VCVTPD2UDQ, + X86_INS_VCVTPH2PS, + X86_INS_VCVTPS2DQ, + X86_INS_VCVTPS2PD, + X86_INS_VCVTPS2PH, + X86_INS_VCVTPS2UDQ, + X86_INS_VCVTSD2SI, + X86_INS_VCVTSD2USI, + X86_INS_VCVTSS2SI, + X86_INS_VCVTSS2USI, + X86_INS_VCVTTPD2DQX, + X86_INS_VCVTTPD2DQ, + X86_INS_VCVTTPD2UDQ, + X86_INS_VCVTTPS2DQ, + X86_INS_VCVTTPS2UDQ, + X86_INS_VCVTUDQ2PD, + X86_INS_VCVTUDQ2PS, + X86_INS_VDIVPD, + X86_INS_VDIVPS, + X86_INS_VDIVSD, + X86_INS_VDIVSS, + X86_INS_VDPPD, + X86_INS_VDPPS, + X86_INS_VERR, + X86_INS_VERW, + X86_INS_VEXTRACTF128, + X86_INS_VEXTRACTF32X4, + X86_INS_VEXTRACTF64X4, + X86_INS_VEXTRACTI128, + X86_INS_VEXTRACTI32X4, + X86_INS_VEXTRACTI64X4, + X86_INS_VEXTRACTPS, + X86_INS_VFMADD132PD, + X86_INS_VFMADD132PS, + X86_INS_VFMADD213PD, + X86_INS_VFMADD213PS, + X86_INS_VFMADDPD, + X86_INS_VFMADD231PD, + X86_INS_VFMADDPS, + X86_INS_VFMADD231PS, + X86_INS_VFMADDSD, + X86_INS_VFMADD213SD, + X86_INS_VFMADD132SD, + X86_INS_VFMADD231SD, + X86_INS_VFMADDSS, + X86_INS_VFMADD213SS, + X86_INS_VFMADD132SS, + X86_INS_VFMADD231SS, + X86_INS_VFMADDSUB132PD, + X86_INS_VFMADDSUB132PS, + X86_INS_VFMADDSUB213PD, + X86_INS_VFMADDSUB213PS, + X86_INS_VFMADDSUBPD, + X86_INS_VFMADDSUB231PD, + X86_INS_VFMADDSUBPS, + X86_INS_VFMADDSUB231PS, + X86_INS_VFMSUB132PD, + X86_INS_VFMSUB132PS, + X86_INS_VFMSUB213PD, + X86_INS_VFMSUB213PS, + X86_INS_VFMSUBADD132PD, + X86_INS_VFMSUBADD132PS, + X86_INS_VFMSUBADD213PD, + X86_INS_VFMSUBADD213PS, + X86_INS_VFMSUBADDPD, + X86_INS_VFMSUBADD231PD, + X86_INS_VFMSUBADDPS, + X86_INS_VFMSUBADD231PS, + X86_INS_VFMSUBPD, + X86_INS_VFMSUB231PD, + X86_INS_VFMSUBPS, + X86_INS_VFMSUB231PS, + X86_INS_VFMSUBSD, + X86_INS_VFMSUB213SD, + X86_INS_VFMSUB132SD, + X86_INS_VFMSUB231SD, + X86_INS_VFMSUBSS, + X86_INS_VFMSUB213SS, + X86_INS_VFMSUB132SS, + X86_INS_VFMSUB231SS, + X86_INS_VFNMADD132PD, + X86_INS_VFNMADD132PS, + X86_INS_VFNMADD213PD, + X86_INS_VFNMADD213PS, + X86_INS_VFNMADDPD, + X86_INS_VFNMADD231PD, + X86_INS_VFNMADDPS, + X86_INS_VFNMADD231PS, + X86_INS_VFNMADDSD, + X86_INS_VFNMADD213SD, + X86_INS_VFNMADD132SD, + X86_INS_VFNMADD231SD, + X86_INS_VFNMADDSS, + X86_INS_VFNMADD213SS, + X86_INS_VFNMADD132SS, + X86_INS_VFNMADD231SS, + X86_INS_VFNMSUB132PD, + X86_INS_VFNMSUB132PS, + X86_INS_VFNMSUB213PD, + X86_INS_VFNMSUB213PS, + X86_INS_VFNMSUBPD, + X86_INS_VFNMSUB231PD, + X86_INS_VFNMSUBPS, + X86_INS_VFNMSUB231PS, + X86_INS_VFNMSUBSD, + X86_INS_VFNMSUB213SD, + X86_INS_VFNMSUB132SD, + X86_INS_VFNMSUB231SD, + X86_INS_VFNMSUBSS, + X86_INS_VFNMSUB213SS, + X86_INS_VFNMSUB132SS, + X86_INS_VFNMSUB231SS, + X86_INS_VFRCZPD, + X86_INS_VFRCZPS, + X86_INS_VFRCZSD, + X86_INS_VFRCZSS, + X86_INS_VORPD, + X86_INS_VORPS, + X86_INS_VXORPD, + X86_INS_VXORPS, + X86_INS_VGATHERDPD, + X86_INS_VGATHERDPS, + X86_INS_VGATHERPF0DPD, + X86_INS_VGATHERPF0DPS, + X86_INS_VGATHERPF0QPD, + X86_INS_VGATHERPF0QPS, + X86_INS_VGATHERPF1DPD, + X86_INS_VGATHERPF1DPS, + X86_INS_VGATHERPF1QPD, + X86_INS_VGATHERPF1QPS, + X86_INS_VGATHERQPD, + X86_INS_VGATHERQPS, + X86_INS_VHADDPD, + X86_INS_VHADDPS, + X86_INS_VHSUBPD, + X86_INS_VHSUBPS, + X86_INS_VINSERTF128, + X86_INS_VINSERTF32X4, + X86_INS_VINSERTF64X4, + X86_INS_VINSERTI128, + X86_INS_VINSERTI32X4, + X86_INS_VINSERTI64X4, + X86_INS_VINSERTPS, + X86_INS_VLDDQU, + X86_INS_VLDMXCSR, + X86_INS_VMASKMOVDQU, + X86_INS_VMASKMOVPD, + X86_INS_VMASKMOVPS, + X86_INS_VMAXPD, + X86_INS_VMAXPS, + X86_INS_VMAXSD, + X86_INS_VMAXSS, + X86_INS_VMCALL, + X86_INS_VMCLEAR, + X86_INS_VMFUNC, + X86_INS_VMINPD, + X86_INS_VMINPS, + X86_INS_VMINSD, + X86_INS_VMINSS, + X86_INS_VMLAUNCH, + X86_INS_VMLOAD, + X86_INS_VMMCALL, + X86_INS_VMOVQ, + X86_INS_VMOVDDUP, + X86_INS_VMOVD, + X86_INS_VMOVDQA32, + X86_INS_VMOVDQA64, + X86_INS_VMOVDQA, + X86_INS_VMOVDQU16, + X86_INS_VMOVDQU32, + X86_INS_VMOVDQU64, + X86_INS_VMOVDQU8, + X86_INS_VMOVDQU, + X86_INS_VMOVHLPS, + X86_INS_VMOVHPD, + X86_INS_VMOVHPS, + X86_INS_VMOVLHPS, + X86_INS_VMOVLPD, + X86_INS_VMOVLPS, + X86_INS_VMOVMSKPD, + X86_INS_VMOVMSKPS, + X86_INS_VMOVNTDQA, + X86_INS_VMOVNTDQ, + X86_INS_VMOVNTPD, + X86_INS_VMOVNTPS, + X86_INS_VMOVSD, + X86_INS_VMOVSHDUP, + X86_INS_VMOVSLDUP, + X86_INS_VMOVSS, + X86_INS_VMOVUPD, + X86_INS_VMOVUPS, + X86_INS_VMPSADBW, + X86_INS_VMPTRLD, + X86_INS_VMPTRST, + X86_INS_VMREAD, + X86_INS_VMRESUME, + X86_INS_VMRUN, + X86_INS_VMSAVE, + X86_INS_VMULPD, + X86_INS_VMULPS, + X86_INS_VMULSD, + X86_INS_VMULSS, + X86_INS_VMWRITE, + X86_INS_VMXOFF, + X86_INS_VMXON, + X86_INS_VPABSB, + X86_INS_VPABSD, + X86_INS_VPABSQ, + X86_INS_VPABSW, + X86_INS_VPACKSSDW, + X86_INS_VPACKSSWB, + X86_INS_VPACKUSDW, + X86_INS_VPACKUSWB, + X86_INS_VPADDB, + X86_INS_VPADDD, + X86_INS_VPADDQ, + X86_INS_VPADDSB, + X86_INS_VPADDSW, + X86_INS_VPADDUSB, + X86_INS_VPADDUSW, + X86_INS_VPADDW, + X86_INS_VPALIGNR, + X86_INS_VPANDD, + X86_INS_VPANDND, + X86_INS_VPANDNQ, + X86_INS_VPANDN, + X86_INS_VPANDQ, + X86_INS_VPAND, + X86_INS_VPAVGB, + X86_INS_VPAVGW, + X86_INS_VPBLENDD, + X86_INS_VPBLENDMD, + X86_INS_VPBLENDMQ, + X86_INS_VPBLENDVB, + X86_INS_VPBLENDW, + X86_INS_VPBROADCASTB, + X86_INS_VPBROADCASTD, + X86_INS_VPBROADCASTMB2Q, + X86_INS_VPBROADCASTMW2D, + X86_INS_VPBROADCASTQ, + X86_INS_VPBROADCASTW, + X86_INS_VPCLMULQDQ, + X86_INS_VPCMOV, + X86_INS_VPCMP, + X86_INS_VPCMPD, + X86_INS_VPCMPEQB, + X86_INS_VPCMPEQD, + X86_INS_VPCMPEQQ, + X86_INS_VPCMPEQW, + X86_INS_VPCMPESTRI, + X86_INS_VPCMPESTRM, + X86_INS_VPCMPGTB, + X86_INS_VPCMPGTD, + X86_INS_VPCMPGTQ, + X86_INS_VPCMPGTW, + X86_INS_VPCMPISTRI, + X86_INS_VPCMPISTRM, + X86_INS_VPCMPQ, + X86_INS_VPCMPUD, + X86_INS_VPCMPUQ, + X86_INS_VPCOMB, + X86_INS_VPCOMD, + X86_INS_VPCOMQ, + X86_INS_VPCOMUB, + X86_INS_VPCOMUD, + X86_INS_VPCOMUQ, + X86_INS_VPCOMUW, + X86_INS_VPCOMW, + X86_INS_VPCONFLICTD, + X86_INS_VPCONFLICTQ, + X86_INS_VPERM2F128, + X86_INS_VPERM2I128, + X86_INS_VPERMD, + X86_INS_VPERMI2D, + X86_INS_VPERMI2PD, + X86_INS_VPERMI2PS, + X86_INS_VPERMI2Q, + X86_INS_VPERMIL2PD, + X86_INS_VPERMIL2PS, + X86_INS_VPERMILPD, + X86_INS_VPERMILPS, + X86_INS_VPERMPD, + X86_INS_VPERMPS, + X86_INS_VPERMQ, + X86_INS_VPERMT2D, + X86_INS_VPERMT2PD, + X86_INS_VPERMT2PS, + X86_INS_VPERMT2Q, + X86_INS_VPEXTRB, + X86_INS_VPEXTRD, + X86_INS_VPEXTRQ, + X86_INS_VPEXTRW, + X86_INS_VPGATHERDD, + X86_INS_VPGATHERDQ, + X86_INS_VPGATHERQD, + X86_INS_VPGATHERQQ, + X86_INS_VPHADDBD, + X86_INS_VPHADDBQ, + X86_INS_VPHADDBW, + X86_INS_VPHADDDQ, + X86_INS_VPHADDD, + X86_INS_VPHADDSW, + X86_INS_VPHADDUBD, + X86_INS_VPHADDUBQ, + X86_INS_VPHADDUBW, + X86_INS_VPHADDUDQ, + X86_INS_VPHADDUWD, + X86_INS_VPHADDUWQ, + X86_INS_VPHADDWD, + X86_INS_VPHADDWQ, + X86_INS_VPHADDW, + X86_INS_VPHMINPOSUW, + X86_INS_VPHSUBBW, + X86_INS_VPHSUBDQ, + X86_INS_VPHSUBD, + X86_INS_VPHSUBSW, + X86_INS_VPHSUBWD, + X86_INS_VPHSUBW, + X86_INS_VPINSRB, + X86_INS_VPINSRD, + X86_INS_VPINSRQ, + X86_INS_VPINSRW, + X86_INS_VPLZCNTD, + X86_INS_VPLZCNTQ, + X86_INS_VPMACSDD, + X86_INS_VPMACSDQH, + X86_INS_VPMACSDQL, + X86_INS_VPMACSSDD, + X86_INS_VPMACSSDQH, + X86_INS_VPMACSSDQL, + X86_INS_VPMACSSWD, + X86_INS_VPMACSSWW, + X86_INS_VPMACSWD, + X86_INS_VPMACSWW, + X86_INS_VPMADCSSWD, + X86_INS_VPMADCSWD, + X86_INS_VPMADDUBSW, + X86_INS_VPMADDWD, + X86_INS_VPMASKMOVD, + X86_INS_VPMASKMOVQ, + X86_INS_VPMAXSB, + X86_INS_VPMAXSD, + X86_INS_VPMAXSQ, + X86_INS_VPMAXSW, + X86_INS_VPMAXUB, + X86_INS_VPMAXUD, + X86_INS_VPMAXUQ, + X86_INS_VPMAXUW, + X86_INS_VPMINSB, + X86_INS_VPMINSD, + X86_INS_VPMINSQ, + X86_INS_VPMINSW, + X86_INS_VPMINUB, + X86_INS_VPMINUD, + X86_INS_VPMINUQ, + X86_INS_VPMINUW, + X86_INS_VPMOVDB, + X86_INS_VPMOVDW, + X86_INS_VPMOVMSKB, + X86_INS_VPMOVQB, + X86_INS_VPMOVQD, + X86_INS_VPMOVQW, + X86_INS_VPMOVSDB, + X86_INS_VPMOVSDW, + X86_INS_VPMOVSQB, + X86_INS_VPMOVSQD, + X86_INS_VPMOVSQW, + X86_INS_VPMOVSXBD, + X86_INS_VPMOVSXBQ, + X86_INS_VPMOVSXBW, + X86_INS_VPMOVSXDQ, + X86_INS_VPMOVSXWD, + X86_INS_VPMOVSXWQ, + X86_INS_VPMOVUSDB, + X86_INS_VPMOVUSDW, + X86_INS_VPMOVUSQB, + X86_INS_VPMOVUSQD, + X86_INS_VPMOVUSQW, + X86_INS_VPMOVZXBD, + X86_INS_VPMOVZXBQ, + X86_INS_VPMOVZXBW, + X86_INS_VPMOVZXDQ, + X86_INS_VPMOVZXWD, + X86_INS_VPMOVZXWQ, + X86_INS_VPMULDQ, + X86_INS_VPMULHRSW, + X86_INS_VPMULHUW, + X86_INS_VPMULHW, + X86_INS_VPMULLD, + X86_INS_VPMULLW, + X86_INS_VPMULUDQ, + X86_INS_VPORD, + X86_INS_VPORQ, + X86_INS_VPOR, + X86_INS_VPPERM, + X86_INS_VPROTB, + X86_INS_VPROTD, + X86_INS_VPROTQ, + X86_INS_VPROTW, + X86_INS_VPSADBW, + X86_INS_VPSCATTERDD, + X86_INS_VPSCATTERDQ, + X86_INS_VPSCATTERQD, + X86_INS_VPSCATTERQQ, + X86_INS_VPSHAB, + X86_INS_VPSHAD, + X86_INS_VPSHAQ, + X86_INS_VPSHAW, + X86_INS_VPSHLB, + X86_INS_VPSHLD, + X86_INS_VPSHLQ, + X86_INS_VPSHLW, + X86_INS_VPSHUFB, + X86_INS_VPSHUFD, + X86_INS_VPSHUFHW, + X86_INS_VPSHUFLW, + X86_INS_VPSIGNB, + X86_INS_VPSIGND, + X86_INS_VPSIGNW, + X86_INS_VPSLLDQ, + X86_INS_VPSLLD, + X86_INS_VPSLLQ, + X86_INS_VPSLLVD, + X86_INS_VPSLLVQ, + X86_INS_VPSLLW, + X86_INS_VPSRAD, + X86_INS_VPSRAQ, + X86_INS_VPSRAVD, + X86_INS_VPSRAVQ, + X86_INS_VPSRAW, + X86_INS_VPSRLDQ, + X86_INS_VPSRLD, + X86_INS_VPSRLQ, + X86_INS_VPSRLVD, + X86_INS_VPSRLVQ, + X86_INS_VPSRLW, + X86_INS_VPSUBB, + X86_INS_VPSUBD, + X86_INS_VPSUBQ, + X86_INS_VPSUBSB, + X86_INS_VPSUBSW, + X86_INS_VPSUBUSB, + X86_INS_VPSUBUSW, + X86_INS_VPSUBW, + X86_INS_VPTESTMD, + X86_INS_VPTESTMQ, + X86_INS_VPTESTNMD, + X86_INS_VPTESTNMQ, + X86_INS_VPTEST, + X86_INS_VPUNPCKHBW, + X86_INS_VPUNPCKHDQ, + X86_INS_VPUNPCKHQDQ, + X86_INS_VPUNPCKHWD, + X86_INS_VPUNPCKLBW, + X86_INS_VPUNPCKLDQ, + X86_INS_VPUNPCKLQDQ, + X86_INS_VPUNPCKLWD, + X86_INS_VPXORD, + X86_INS_VPXORQ, + X86_INS_VPXOR, + X86_INS_VRCP14PD, + X86_INS_VRCP14PS, + X86_INS_VRCP14SD, + X86_INS_VRCP14SS, + X86_INS_VRCP28PD, + X86_INS_VRCP28PS, + X86_INS_VRCP28SD, + X86_INS_VRCP28SS, + X86_INS_VRCPPS, + X86_INS_VRCPSS, + X86_INS_VRNDSCALEPD, + X86_INS_VRNDSCALEPS, + X86_INS_VRNDSCALESD, + X86_INS_VRNDSCALESS, + X86_INS_VROUNDPD, + X86_INS_VROUNDPS, + X86_INS_VROUNDSD, + X86_INS_VROUNDSS, + X86_INS_VRSQRT14PD, + X86_INS_VRSQRT14PS, + X86_INS_VRSQRT14SD, + X86_INS_VRSQRT14SS, + X86_INS_VRSQRT28PD, + X86_INS_VRSQRT28PS, + X86_INS_VRSQRT28SD, + X86_INS_VRSQRT28SS, + X86_INS_VRSQRTPS, + X86_INS_VRSQRTSS, + X86_INS_VSCATTERDPD, + X86_INS_VSCATTERDPS, + X86_INS_VSCATTERPF0DPD, + X86_INS_VSCATTERPF0DPS, + X86_INS_VSCATTERPF0QPD, + X86_INS_VSCATTERPF0QPS, + X86_INS_VSCATTERPF1DPD, + X86_INS_VSCATTERPF1DPS, + X86_INS_VSCATTERPF1QPD, + X86_INS_VSCATTERPF1QPS, + X86_INS_VSCATTERQPD, + X86_INS_VSCATTERQPS, + X86_INS_VSHUFPD, + X86_INS_VSHUFPS, + X86_INS_VSQRTPD, + X86_INS_VSQRTPS, + X86_INS_VSQRTSD, + X86_INS_VSQRTSS, + X86_INS_VSTMXCSR, + X86_INS_VSUBPD, + X86_INS_VSUBPS, + X86_INS_VSUBSD, + X86_INS_VSUBSS, + X86_INS_VTESTPD, + X86_INS_VTESTPS, + X86_INS_VUNPCKHPD, + X86_INS_VUNPCKHPS, + X86_INS_VUNPCKLPD, + X86_INS_VUNPCKLPS, + X86_INS_VZEROALL, + X86_INS_VZEROUPPER, + X86_INS_WAIT, + X86_INS_WBINVD, + X86_INS_WRFSBASE, + X86_INS_WRGSBASE, + X86_INS_WRMSR, + X86_INS_XABORT, + X86_INS_XACQUIRE, + X86_INS_XBEGIN, + X86_INS_XCHG, + X86_INS_FXCH, + X86_INS_XCRYPTCBC, + X86_INS_XCRYPTCFB, + X86_INS_XCRYPTCTR, + X86_INS_XCRYPTECB, + X86_INS_XCRYPTOFB, + X86_INS_XEND, + X86_INS_XGETBV, + X86_INS_XLATB, + X86_INS_XRELEASE, + X86_INS_XRSTOR, + X86_INS_XRSTOR64, + X86_INS_XSAVE, + X86_INS_XSAVE64, + X86_INS_XSAVEOPT, + X86_INS_XSAVEOPT64, + X86_INS_XSETBV, + X86_INS_XSHA1, + X86_INS_XSHA256, + X86_INS_XSTORE, + X86_INS_XTEST, + + X86_INS_ENDING, // mark the end of the list of insn +} x86_insn; + +//> Group of X86 instructions +typedef enum x86_insn_group { + X86_GRP_INVALID = 0, // = CS_GRP_INVALID + + //> Generic groups + // all jump instructions (conditional+direct+indirect jumps) + X86_GRP_JUMP, // = CS_GRP_JUMP + // all call instructions + X86_GRP_CALL, // = CS_GRP_CALL + // all return instructions + X86_GRP_RET, // = CS_GRP_RET + // all interrupt instructions (int+syscall) + X86_GRP_INT, // = CS_GRP_INT + // all interrupt return instructions + X86_GRP_IRET, // = CS_GRP_IRET + + //> Architecture-specific groups + X86_GRP_VM = 128, // all virtualization instructions (VT-x + AMD-V) + X86_GRP_3DNOW, + X86_GRP_AES, + X86_GRP_ADX, + X86_GRP_AVX, + X86_GRP_AVX2, + X86_GRP_AVX512, + X86_GRP_BMI, + X86_GRP_BMI2, + X86_GRP_CMOV, + X86_GRP_F16C, + X86_GRP_FMA, + X86_GRP_FMA4, + X86_GRP_FSGSBASE, + X86_GRP_HLE, + X86_GRP_MMX, + X86_GRP_MODE32, + X86_GRP_MODE64, + X86_GRP_RTM, + X86_GRP_SHA, + X86_GRP_SSE1, + X86_GRP_SSE2, + X86_GRP_SSE3, + X86_GRP_SSE41, + X86_GRP_SSE42, + X86_GRP_SSE4A, + X86_GRP_SSSE3, + X86_GRP_PCLMUL, + X86_GRP_XOP, + X86_GRP_CDI, + X86_GRP_ERI, + X86_GRP_TBM, + X86_GRP_16BITMODE, + X86_GRP_NOT64BITMODE, + X86_GRP_SGX, + X86_GRP_DQI, + X86_GRP_BWI, + X86_GRP_PFI, + X86_GRP_VLX, + X86_GRP_SMAP, + X86_GRP_NOVLX, + + X86_GRP_ENDING +} x86_insn_group; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/xcore.h b/include/xcore.h new file mode 100644 index 0000000..aaf5912 --- /dev/null +++ b/include/xcore.h @@ -0,0 +1,237 @@ +#ifndef CAPSTONE_XCORE_H +#define CAPSTONE_XCORE_H + +/* Capstone Disassembly Engine */ +/* By Nguyen Anh Quynh , 2014 */ + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(_MSC_VER) || !defined(_KERNEL_MODE) +#include +#endif + +#include "platform.h" + +#ifdef _MSC_VER +#pragma warning(disable:4201) +#endif + +//> Operand type for instruction's operands +typedef enum xcore_op_type { + XCORE_OP_INVALID = 0, // = CS_OP_INVALID (Uninitialized). + XCORE_OP_REG, // = CS_OP_REG (Register operand). + XCORE_OP_IMM, // = CS_OP_IMM (Immediate operand). + XCORE_OP_MEM, // = CS_OP_MEM (Memory operand). +} xcore_op_type; + +// Instruction's operand referring to memory +// This is associated with XCORE_OP_MEM operand type above +typedef struct xcore_op_mem { + uint8_t base; // base register + uint8_t index; // index register + int32_t disp; // displacement/offset value + int direct; // +1: forward, -1: backward +} xcore_op_mem; + +// Instruction operand +typedef struct cs_xcore_op { + xcore_op_type type; // operand type + union { + unsigned int reg; // register value for REG operand + int32_t imm; // immediate value for IMM operand + xcore_op_mem mem; // base/disp value for MEM operand + }; +} cs_xcore_op; + +// Instruction structure +typedef struct cs_xcore { + // Number of operands of this instruction, + // or 0 when instruction has no operand. + uint8_t op_count; + cs_xcore_op operands[8]; // operands for this instruction. +} cs_xcore; + +//> XCore registers +typedef enum xcore_reg { + XCORE_REG_INVALID = 0, + + XCORE_REG_CP, + XCORE_REG_DP, + XCORE_REG_LR, + XCORE_REG_SP, + XCORE_REG_R0, + XCORE_REG_R1, + XCORE_REG_R2, + XCORE_REG_R3, + XCORE_REG_R4, + XCORE_REG_R5, + XCORE_REG_R6, + XCORE_REG_R7, + XCORE_REG_R8, + XCORE_REG_R9, + XCORE_REG_R10, + XCORE_REG_R11, + + //> pseudo registers + XCORE_REG_PC, // pc + + // internal thread registers + // see The-XMOS-XS1-Architecture(X7879A).pdf + XCORE_REG_SCP, // save pc + XCORE_REG_SSR, // save status + XCORE_REG_ET, // exception type + XCORE_REG_ED, // exception data + XCORE_REG_SED, // save exception data + XCORE_REG_KEP, // kernel entry pointer + XCORE_REG_KSP, // kernel stack pointer + XCORE_REG_ID, // thread ID + + XCORE_REG_ENDING, // <-- mark the end of the list of registers +} xcore_reg; + +//> XCore instruction +typedef enum xcore_insn { + XCORE_INS_INVALID = 0, + + XCORE_INS_ADD, + XCORE_INS_ANDNOT, + XCORE_INS_AND, + XCORE_INS_ASHR, + XCORE_INS_BAU, + XCORE_INS_BITREV, + XCORE_INS_BLA, + XCORE_INS_BLAT, + XCORE_INS_BL, + XCORE_INS_BF, + XCORE_INS_BT, + XCORE_INS_BU, + XCORE_INS_BRU, + XCORE_INS_BYTEREV, + XCORE_INS_CHKCT, + XCORE_INS_CLRE, + XCORE_INS_CLRPT, + XCORE_INS_CLRSR, + XCORE_INS_CLZ, + XCORE_INS_CRC8, + XCORE_INS_CRC32, + XCORE_INS_DCALL, + XCORE_INS_DENTSP, + XCORE_INS_DGETREG, + XCORE_INS_DIVS, + XCORE_INS_DIVU, + XCORE_INS_DRESTSP, + XCORE_INS_DRET, + XCORE_INS_ECALLF, + XCORE_INS_ECALLT, + XCORE_INS_EDU, + XCORE_INS_EEF, + XCORE_INS_EET, + XCORE_INS_EEU, + XCORE_INS_ENDIN, + XCORE_INS_ENTSP, + XCORE_INS_EQ, + XCORE_INS_EXTDP, + XCORE_INS_EXTSP, + XCORE_INS_FREER, + XCORE_INS_FREET, + XCORE_INS_GETD, + XCORE_INS_GET, + XCORE_INS_GETN, + XCORE_INS_GETR, + XCORE_INS_GETSR, + XCORE_INS_GETST, + XCORE_INS_GETTS, + XCORE_INS_INCT, + XCORE_INS_INIT, + XCORE_INS_INPW, + XCORE_INS_INSHR, + XCORE_INS_INT, + XCORE_INS_IN, + XCORE_INS_KCALL, + XCORE_INS_KENTSP, + XCORE_INS_KRESTSP, + XCORE_INS_KRET, + XCORE_INS_LADD, + XCORE_INS_LD16S, + XCORE_INS_LD8U, + XCORE_INS_LDA16, + XCORE_INS_LDAP, + XCORE_INS_LDAW, + XCORE_INS_LDC, + XCORE_INS_LDW, + XCORE_INS_LDIVU, + XCORE_INS_LMUL, + XCORE_INS_LSS, + XCORE_INS_LSUB, + XCORE_INS_LSU, + XCORE_INS_MACCS, + XCORE_INS_MACCU, + XCORE_INS_MJOIN, + XCORE_INS_MKMSK, + XCORE_INS_MSYNC, + XCORE_INS_MUL, + XCORE_INS_NEG, + XCORE_INS_NOT, + XCORE_INS_OR, + XCORE_INS_OUTCT, + XCORE_INS_OUTPW, + XCORE_INS_OUTSHR, + XCORE_INS_OUTT, + XCORE_INS_OUT, + XCORE_INS_PEEK, + XCORE_INS_REMS, + XCORE_INS_REMU, + XCORE_INS_RETSP, + XCORE_INS_SETCLK, + XCORE_INS_SET, + XCORE_INS_SETC, + XCORE_INS_SETD, + XCORE_INS_SETEV, + XCORE_INS_SETN, + XCORE_INS_SETPSC, + XCORE_INS_SETPT, + XCORE_INS_SETRDY, + XCORE_INS_SETSR, + XCORE_INS_SETTW, + XCORE_INS_SETV, + XCORE_INS_SEXT, + XCORE_INS_SHL, + XCORE_INS_SHR, + XCORE_INS_SSYNC, + XCORE_INS_ST16, + XCORE_INS_ST8, + XCORE_INS_STW, + XCORE_INS_SUB, + XCORE_INS_SYNCR, + XCORE_INS_TESTCT, + XCORE_INS_TESTLCL, + XCORE_INS_TESTWCT, + XCORE_INS_TSETMR, + XCORE_INS_START, + XCORE_INS_WAITEF, + XCORE_INS_WAITET, + XCORE_INS_WAITEU, + XCORE_INS_XOR, + XCORE_INS_ZEXT, + + XCORE_INS_ENDING, // <-- mark the end of the list of instructions +} xcore_insn; + +//> Group of XCore instructions +typedef enum xcore_insn_group { + XCORE_GRP_INVALID = 0, // = CS_GRP_INVALID + + //> Generic groups + // all jump instructions (conditional+direct+indirect jumps) + XCORE_GRP_JUMP, // = CS_GRP_JUMP + + XCORE_GRP_ENDING, // <-- mark the end of the list of groups +} xcore_insn_group; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/resonance.c b/resonance.c index 2c3d161..75c641f 100644 --- a/resonance.c +++ b/resonance.c @@ -140,9 +140,6 @@ int main(){ CreateProcess("test.exe", NULL, NULL, NULL, FALSE, CREATE_SUSPENDED | CREATE_NEW_CONSOLE, NULL, NULL, &startupInfo, &processInfo); - - //HANDLE address = VirtualAllocEx(processInfo.hProcess, NULL, 50, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); - DWORD moduleSize = 0, baseAddr = 0; ResumeThread(processInfo.hThread); @@ -157,12 +154,8 @@ int main(){ FUNCTION function; function.startAddr = function.size = 0; getFunctionsToEncrypt(processInfo.hProcess, baseAddr, moduleSize, &function); - - - PASM_INSTRUCTION pAsmInstructionList = NULL; - addAllAsmInstructions(&pAsmInstructionList); - - if(interptFunction(processInfo.hProcess, function, pAsmInstructionList)) + + if(interptFunction(processInfo.hProcess, function)) MessageBoxA(NULL,"YEAH", "YEAH", 0); else MessageBoxA(NULL,"NO", "NO", 0); diff --git a/xor.h b/xor.h index 4801a07..829674e 100644 --- a/xor.h +++ b/xor.h @@ -2,6 +2,7 @@ #include #include #include +#include typedef struct _function{ @@ -11,7 +12,7 @@ typedef struct _function{ }FUNCTION, *PFUNCTION; -typedef struct __attribute__((packed)){ +typedef struct __attribute__((packed)) _abs_Instruction{ BYTE opcode; BYTE modReg; @@ -19,92 +20,17 @@ typedef struct __attribute__((packed)){ DWORD address; DWORD idInStorage; // diffrent name so my head doesn't explode }; + DWORD bytePosition; //Where in the buffer it should be replaced + DWORD originalSize; + BOOL alreadyStored; + struct _abs_Instruction *next; }ABS_INSTRUCTION, *PABS_INSTRUCTION; -typedef struct __attribute__((packed)) _asmInstruction{ - - BYTE opcode; - BYTE size; - - union{ - BOOL needToFix; - PABS_INSTRUCTION fixedInstruction; - }; - - union{ - BOOL variableSize; - BYTE size2; //used to store the "new" size of the needToFix fixed instruction - }; - - BOOL sharedOpcode; - BYTE regValue;//Only used if sharedOpcode is used - void (*defineSize)(struct _asmInstruction *pThis, const unsigned char *buffer);//Only used if variableSize is true - struct _asmInstruction *next; - -}ASM_INSTRUCTION, *PASM_INSTRUCTION; - -typedef struct _absAddressStorage{ - - PABS_INSTRUCTION instruction; //easier to edit it - BOOLEAN alreadyInStorage; - struct _absAddressStorage *next; - - -}ABS_ADDRESS_STORAGE, *PABS_ADDRESS_STORAGE; - BOOL getModuleHandle(DWORD processId, const char* name, DWORD* baseAddr, DWORD* moduleSize); - void freeLinkedList(void **entry, DWORD sizeOfEntry); -void addAsmInstruction(PASM_INSTRUCTION pAsmInstruction, BYTE opcode, BYTE size, BOOL needToFix, BOOL variableSize, BOOL sharedOpcode, BYTE regValue,void* fixSizeFunction); -void printAsmInstructions(PASM_INSTRUCTION pAsmInstruction); -void addAllAsmInstructions(PASM_INSTRUCTION *ppAsmInstruction); -void addAsmInstruction(PASM_INSTRUCTION pAsmInstruction, BYTE opcode, BYTE size, BOOL needToFix, BOOL variableSize, BOOL sharedOpcode, BYTE regValue,void* fixSizeFunction); - - -void getMovSize(PASM_INSTRUCTION pAsmInstruction, const unsigned char *buffer); -void getOrSize(PASM_INSTRUCTION pAsmInstruction, const unsigned char *buffer); -void getTestSize(PASM_INSTRUCTION pAsmInstruction, const unsigned char *buffer); -void getXorSize(PASM_INSTRUCTION pAsmInstruction, const unsigned char *buffer); - -PASM_INSTRUCTION getCurrentInstruction(const unsigned char *buffer, PASM_INSTRUCTION pAsmInstructionList); -BOOL analyzeFunction(const unsigned char *buffer, DWORD size,PASM_INSTRUCTION pAsmInstructionList, PASM_INSTRUCTION final); -BOOL interptFunction(HANDLE hProcess, FUNCTION function, PASM_INSTRUCTION pAsmInstructionList); -BOOL fixRelativeAddresses(PASM_INSTRUCTION pAsmInstruction, FUNCTION function,const unsigned char* buffer); -BOOL addAbsoluteAddressesToStorage(PASM_INSTRUCTION pAsmInstruction, PABS_ADDRESS_STORAGE absAddrStorage); - -unsigned char *convertFunction(PASM_INSTRUCTION pAsmInstruction,const unsigned char* buffer,DWORD size, DWORD allocatedMemoryAddress); -DWORD getConvertedFunctionSize(PASM_INSTRUCTION pAsmInstruction); - -BOOL addAbsoluteAddressesToStorage(PASM_INSTRUCTION pAsmInstruction, PABS_ADDRESS_STORAGE absAddrStorage); -BOOL countStorageId(PABS_ADDRESS_STORAGE absAddrStorage); -BOOL fixAbsoluteAddresses(PABS_ADDRESS_STORAGE absAddrStorage, DWORD* counter); - -//Only first 2 bits matter -#define REGISTER_ADDRESSING 3 //11 -#define FOUR_BYTE_DISPLACEMENT 2 //10 -#define ONE_BYTE_DISPLACEMENT 1 //01 -#define REGISTER_INDIRECT_ADDRESSING (0)//00 - -//REGISTER_INDIRECT_ADDRESSING has more modes -#define SIB_NO_DISPLACEMENT (1<<2) //100 -#define DISPLACEMENT_ONLY (5 << 0) //101 - - -#define DEFAULT_SIZE(x) \ - pAsmInstruction->size = x; \ - tmp = buffer[1] & 7; - -#define SIB_INSTRUCTION \ - if(tmp == SIB_NO_DISPLACEMENT)\ - pAsmInstruction->size += 1; - -#define DISPLACEMENT_ONLY_INSTRUCTION \ - if(tmp == DISPLACEMENT_ONLY)\ - pAsmInstruction->size += 4; - -#define SIB_AND_DISPLACEMENT_INSTRUCTION \ - SIB_INSTRUCTION \ - DISPLACEMENT_ONLY_INSTRUCTION - \ No newline at end of file +BOOL interptFunction(HANDLE hProcess, FUNCTION function); +BOOL fixRelativeJmpOrCall(int64_t jmpLocation, DWORD numBytes, PABS_INSTRUCTION *pAbsInstruction, DWORD originalSize,BOOLEAN isJmp); +BYTE* createNewFunction(const BYTE *originalFunction, DWORD newFunctionSize, PABS_INSTRUCTION pAbsInstruction); +BOOL getAbsoluteAddressStorage(HANDLE hProcess, PABS_INSTRUCTION pAbsInstruction); \ No newline at end of file