|
[求助]請問關於C++問題
都測過了 在 Mac 一切正常 你說的慢或者錯誤可能是 尋址模式錯誤 不然就是 instructions implementation 錯誤 之前在 Mac 指令集模擬錯誤就是這樣 指令集模擬錯誤 只會造成核心無法啟動 或者APP 報錯退出 我沒辦法錄影 截圖給你看=_= |
|
[求助]請問關於C++問題
手冊我整理了 http://www.insanelymac.com/forum/topic/304258-ssse3-opcode-mode-for-amd-opemu/ 目前在 Mac 上測試 SSSE3 模擬器 沒有比較慢 測試結果 SSEPlus Rev.8 是我的版本 http://www.insanelymac.com/forum/topic/302075-amd-yosemite-kernel-testing-for-help-use-the-help-topic/page-44 附件是改好的 SSSE3 模擬器 尋址模式 我只加到REX VEX 還在研究中... 指令集模擬 確實可行 |
|
[求助]請問關於C++問題
感謝我需要的就是這個 |
|
[求助]請問關於C++問題
Intel 描述太雜了 我現在只針對 SSSE3 跟 SSE3 就好了 那 dppdpp大 可以幫我看一下 我現在理解的 MODRM 跟 SIB 尋址模式對不對 是不是有遺漏的尋址模式?? ModRM / SIB 尋址模式 4=ESP/RSP 5=EBP/RBP 一般尋址模式 mod 00b address = R/M REG mod 01b address = R/M REG + DISP8 OFFSET mod 10b address = R/M REG + DISP32 OFFSET SIB 模式 R/M = 04 RSP/ESP mod 00b base = 5 & index = 4 address = DISP32 OFFSET base = 5 address = DISP32 OFFSET + (INDEX REG * SCALE) index = 4 不是 base = 5 address = BASE REG index = 4 base = 5 都不是 address = BASE REG + (INDEX REG * SCALE) mod 01b index = 4 address = BASE REG + DISP8 OFFSET 不是 index = 4 address = BASE REG + (INDEX REG * SCALE) + DISP8 OFFSET mod 10b index = 4 address = BASE REG + DISP32 OFFSET 不是 index = 4 address = BASE REG + (INDEX REG * SCALE) + DISP32 OFFSET 特殊模式 R/M = 05 EBP/RBP mod 00b R/M REG = 5 address = DISP32 OFFSET 括弧內的值 (INDEX REG * SCALE) SIB scale 域 00b 的時候 是 (index * 1) SIB scale 域 01b 的時候 是 (index * 2) SIB scale 域 10b 的時候 是 (index * 4) SIB scale 域 11b 的時候 是 (index * 8) 的值 這個好像有問題 的到的是 0 1 2 3 uint8_t scale = ModRM[1] >> 6; 在 C++ 我用 (index * (1 <<scale)) 這樣寫正確嗎 附件是我修改的模擬器源碼 |
|
[求助]請問關於C++問題
hi dppdpp 大 我有看 intel 手冊了 但我之前下載到的是2003版 內容只到SSE2 昨天我找到2015 版 稍微翻一下 有些不太懂 rex 前綴是指像 SSSE3 這類前綴有0x66開頭的指令嗎 SSSE3 分為兩種模式 例如 PHADDD 66 0f 38 02 <<< 這個 66 開頭是 m128 類型 使用xmm 暫存器 如果是 0f 38 02 <<< 這個沒有66前綴 是 m64 類型使用 mm 暫存器 現在我不清楚的有2點 暫存器用到 xmm0 - 15 的是只要在64bit OS 的環境下都是 xmm 0-15嗎 還是 32 bit OS 也有用 xmm 0-15 mm 暫存器 在64-bit OS平台 也使用mm0-15嗎 還是只要是 66 前綴開頭的 就是使用 xmm0 - 15 或者是說 m128 使用 xmm8-15 m64 使用mm0-8 另外 SIB 模式 是64 bit 才有 還是只要是前綴66就有 32 bit OS 平台有 SIB 模式嗎 |
|
[求助]請問關於C++問題
SSSE3 模擬器我是用在mac上的 Mac OS X 10.6 - 目前10.10 系統運行指令集需求 MMX SSE SSE2 SSE3 SSSE3 在AMD K8 K10 都具備 MMX - SSE3 但惟獨缺少 SSSE3 K10 FX 跟最新的APU 就全系列支援了 還有SSE4x 跟 AVX 我當然知道換CPU 就好了 但是我還是希望可以完成這個模擬器 如果成功 那大概也可以應用到每個平台 Windows 核心除外 因為 微軟沒有開放核心的源碼 MS 下大概只能用在APP ------------------------ 我現在還有一個問題 例如這個SSSE3 指令 phaddw 在MSDN 上模擬的資料 https://msdn.microsoft.com/en-us/library/bb514103.aspx 我們已經知道 __m128i A = (*ModRM >> 3) & 0x7 __m128i B = *ModRM & 0x7 那換成這個指令 https://msdn.microsoft.com/en-us/library/bb531427.aspx __m128i A = (*ModRM >> 3) & 0x7 __m128i mask Mask 得值是怎麼來的 該怎麼求MASK ??? THX |
|
[求助]請問關於C++問題
[QUOTE=dppdpp;1351158]address = (uint64_t)ModRM[consumed]; 这种语法肯定是64位的取值,但正确与否要看你的地址空间,是32位,还是64位,如果是32这种表述无关紧要,多了几个零而已,如果64位,要向后再取四个byte的数值。 另外你说的cpu指令集不支持问题,大部份是cpu型号问题...[/QUOTE] pmulhrsw xmm4, xmmword [ds:0x23270] 這個是用Debuger 打開二進制文件 看到的opcode 指標(指針)是 0x23270 xmmword 我不知道是幾位 我知道 dword 是 4-byte 那假設 xmm4, xmmword [rax+0x23270] 如果 rax=2 那就是 2+23270 = 23272 指標 addr = 0x23272 pmulhrsw 的性質我不知道 我最近剛摸索這東西 應該是 指標addr的值 長度xmmword 用pmulhrsw的方式 移到 xmm4 吧 我知道 mov eax ,dword ptr[0x00401000] 是把指標 addr 0x00401000 的值 長度4-byte 移到 eax EAX <- ptr[0x00401000] dword 假設 00401000 的值是 ffffffff 那就是 把 ffffffff 移到eax 你看到的 000000000001dd36 這個是addr 在 000000000001dd36 上的opcode pmulhrsw xmm4, xmmword [ds:0x23270] 看圖你應該明白吧 編譯後的二進制文件裡面的操作代碼都是這樣的 SSE指令集 Opcode 長度 幾byte 用Debuger看都是絕對值 沒有例外 |
|
[求助]請問關於C++問題
[QUOTE=dppdpp;1351130]//0 1 2 3 4 5 6 7 8 //66 0F 38 01 05 01 02 03 04 //phaddw xmm0, xmmword ptr [cs:04030201h] 66 = 宽度调整 0f 38 = 三字节前缀 01 = Opcode 05...[/QUOTE] 我說的是 語法正不正確 取後面4byte 當addr 像這樣 uint32_t address = (uint32_t)ModRM[consumed]; 還是 uint64_t 或是 __uint64_t uint32_t 是 4個byte 對嗎 但是64bit模式 addr 好像都是8個byte 例如 0x0000000004030201 但是如果這樣 address = (uint64_t)ModRM[consumed]; address 會不會多取後面4個byte 變成 0x0?0?0?0?04030201 我知道要看手冊啊 但我現在看到的是 編譯後的二進制文件 裡面有指令集的操作代碼 例如 某二進制文件裡面的opcode 000000000001dd36 pmulhrsw xmm4, xmmword [ds:0x23270] 在0x000000000001dd36h 有這個指令 pmulhrsw xmm4, xmmword [ds:0x23270] 如果你的CPU不支援這個指令集 那kernel 就會返回錯誤操作代碼 app會異常或退出 所以變成 app -> CPU 指令不支援 -> 錯誤 這個addr 是取二進制文件裡面的opcode 例如在該指令 pmulhrsw xmm4, xmmword [ds:0x04030201] 最後面四個字節 |
|
[求助]請問關於C++問題
我重新改寫這個函數 但是我不知道這樣改是不是正確的 我按照我再 IDA Pro 上看到的opcode 為準 這個我有疑問的是 mod 0 - 2 計算 Pointer address 是不是正確的 例如: //0 1 2 3 4 5 6 7 8 //66 0F 38 01 05 01 02 03 04 //phaddw xmm0, xmmword ptr [cs:04030201h] offset + 6 的四個byte(字節) 是指標(指針) 的位址(地址) 兩種寫法哪個正確 1. consumed++; __uint64_t ModRMVal = (__uint64_t)&ModRM[consumed]; __int32_t *ModRMCast = (__int32_t *)ModRMVal; address = *(uint32_t*)&r64->isf.rip + *ModRMCast; consumed += 3; 2. consumed++; address = (uint32_t)ModRM[consumed]; consumed += 3; 最後 address 的數值是 kernel_trap 裡面的 address if(kernel_trap) { if(size_128) ((ssp_m128*)src)->ui = *(__uint128_t *)address; else ((ssp_m64*)src)->u64 = *(uint64_t *)address; } else { //printf("xnu: da = %llx, rsp=%llx, rip=%llx\n", address, reg_sel[4], r64->isf.rip); if(size_128) copyin(address, (char*)& ((ssp_m128*)src)->ui, 16); else copyin(address, (char*)& ((ssp_m64*)src)->u64, 8); } 64-bit mode int operands(uint8_t *ModRM, uint8_t hsrc, uint8_t hdst, void *src, void *dst, unsigned int longmode, x86_saved_state_t *saved_state, int kernel_trap, int size_128, int ins_size) { unsigned char num_src = *ModRM & 0x7; // 1 byte + 1 unsigned char num_dst = (*ModRM >> 3) & 0x7; //8 byte + 1 unsigned char mod = *ModRM >> 6; // 40 byte + 1 int consumed = 1; //modrm + 1 byte if(hsrc) num_src += 8; if(hdst) num_dst += 8; if(size_128) getxmm((ssp_m128*)dst, num_dst); else getmm((ssp_m64*)dst, num_dst); if(mod == 3) { if(size_128) getxmm((ssp_m128*)src, num_src); else getmm((ssp_m64*)src, num_src); } // AnV - Implemented 64-bit fetch else if ((longmode = is_saved_state64(saved_state))) { uint64_t address; // DST is always an XMM register. decode for SRC. x86_saved_state64_t *r64 = saved_state64(saved_state); __uint64_t reg_sel[8] = {r64->rax, r64->rcx, r64->rdx, r64->rbx, r64->isf.rsp, r64->rbp, r64->rsi, r64->rdi}; if(hsrc) printf("opemu error: high reg ssse\n"); // FIXME if (mod == 0) { if (num_src == 4) { uint8_t scale = ModRM[1] >> 6; //40 byte + 1 uint8_t base = ModRM[1] & 0x7; //1 byte + 1 reg loop uint8_t index = (ModRM[1] >> 3) & 0x7; //8 byte + 1 reg loop if(base == 5) { consumed += 2; //modrm[1] = byte[5] //0 1 2 3 4 5 6 7 8 9 //66 0F 38 01 04 05 04 03 02 01 //phaddw xmm0, xmmword [ds:0x1020304+rax] //__uint64_t ModRMVal = (__uint64_t)&ModRM[consumed]; //__int32_t *ModRMCast = (__int32_t *)ModRMVal; //address = /* *(uint32_t*)&r64->isf.rip + */ *ModRMCast + reg_sel[index]; address = (uint32_t)ModRM[consumed] + reg_sel[index]; consumed += 3; } else { if (index == 4) { //0 1 2 3 4 5 //66 0F 38 01 04 61 //phaddw xmm0, xmmword [ds:rcx] address = reg_sel[base]; consumed++; } else { //0 1 2 3 4 5 //66 0F 38 01 04 44 //phaddw xmm0, xmmword ptr [rsp+rax*2] address = reg_sel[base] + (reg_sel[index] * (1<<scale)); consumed++; } } } else if (num_src == 5) { consumed++; //0 1 2 3 4 5 6 7 8 //66 0F 38 01 05 01 02 03 04 //phaddw xmm0, xmmword ptr [cs:04030201h] __uint64_t ModRMVal = (__uint64_t)&ModRM[consumed]; __int32_t *ModRMCast = (__int32_t *)ModRMVal; address = *(uint32_t*)&r64->isf.rip + *ModRMCast; //address = (uint32_t)ModRM[consumed]; consumed += 3; } else { //0 1 2 3 4 //66 0F 38 01 03 //phaddw xmm0, xmmword [ds:rbx] address = reg_sel[num_src]; } } if (mod == 1) { if(num_src == 4) { uint8_t scale = ModRM[1] >> 6; //40 byte + 1 uint8_t base = ModRM[1] & 0x7; //1 byte + 1 reg loop uint8_t index = (ModRM[1] >> 3) & 0x7; //8 byte + 1 reg loop if (index == 4) { //0 1 2 3 4 5 6 //66 0F 38 01 44 27 80 //phaddw xmm0, xmmword ptr [rdi-80h] consumed+= 2; address = reg_sel[base] + (int8_t)ModRM[consumed]; } else { //0 1 2 3 4 5 6 //66 0F 38 01 44 44 80 //phaddw xmm0, xmmword ptr [rsp+rax*2-80h] consumed+= 2; address = reg_sel[base] + (reg_sel[index] * (1<<scale)) + (int8_t)ModRM[consumed]; } } else { //0 1 2 3 4 5 //66 0F 38 01 43 01 //phaddw xmm0, xmmword [ds:rbx+0x1] consumed++; address = reg_sel[num_src] + (int8_t)ModRM[consumed]; } } if (mod == 2) { if(num_src == 4) { uint8_t scale = ModRM[1] >> 6; //40 byte + 1 uint8_t base = ModRM[1] & 0x7; //1 byte + 1 reg loop uint8_t index = (ModRM[1] >> 3) & 0x7; //8 byte + 1 reg loop if (index == 4) { //0 1 2 3 4 5 6 7 8 9 //66 0F 38 01 84 20 04 03 02 01 //phaddw xmm0, xmmword ptr [rax+1020304h] consumed += 2; address = reg_sel[base] + (uint32_t)ModRM[consumed]; consumed += 3; } else { //0 1 2 3 4 5 6 7 8 9 //66 0F 38 01 84 44 04 03 02 01 //phaddw xmm0, xmmword ptr [rsp+rax*2+1020304h] consumed += 2; //__uint64_t ModRMVal = (__uint64_t)&ModRM[consumed]; //__int32_t *ModRMCast = (__int32_t *)ModRMVal; //address = reg_sel[base] + (reg_sel[index] * (1<<scale)) + /* *(uint32_t*)&r64->isf.rip + */ *ModRMCast; address = reg_sel[base] + (reg_sel[index] * (1<<scale)) + (uint32_t)ModRM[consumed]; consumed += 3; } } else { //0 1 2 3 4 5 6 7 8 //66 0F 38 01 83 01 02 03 04 //phaddw xmm0, xmmword [ds:rbx+0x4030201] consumed++; //__uint64_t ModRMVal = (__uint64_t)&ModRM[consumed]; //__int32_t *ModRMCast = (__int32_t *)ModRMVal; //address = reg_sel[num_src] + /* *(uint32_t*)&r64->isf.rip + */ *ModRMCast; address = reg_sel[num_src] + (uint32_t)ModRM[consumed]; consumed += 3; } } // address is good now, do read and store operands. if(kernel_trap) { if(size_128) ((ssp_m128*)src)->ui = *(__uint128_t *)address; else ((ssp_m64*)src)->u64 = *(uint64_t *)address; } else { //printf("xnu: da = %llx, rsp=%llx, rip=%llx\n", address, reg_sel[4], r64->isf.rip); if(size_128) copyin(address, (char*)& ((ssp_m128*)src)->ui, 16); else copyin(address, (char*)& ((ssp_m64*)src)->u64, 8); } } return consumed; } |
|
|
|
[求助]請問關於C++問題
我是想試著改 SSSE3 模擬器 給AMD老CPU用的 我不知道這樣修改對不對 指令部份我用 SSEPlus 模擬的 目前測試是有bug jpg圖片顯示顏色不正常 int ssse3_emu(uint8_t *instruction, x86_saved_state_t *state, int longmode, int kernel_trap) { // pointer to the current byte we're working on uint8_t *bytep = instruction; int ins_size = 0; int is_128 = 0, src_higher = 0, dst_higher = 0; ssp_m128 xmmsrc, xmmdst, xmmres; ssp_m64 mmsrc,mmdst, mmres; /** We can get a few prefixes, in any order: ** 66 throws into 128-bit xmm mode. ** 40->4f use higher xmm registers. **/ if(*bytep == 0x66) { is_128 = 1; bytep++; ins_size++; } if((*bytep & 0xF0) == 0x40) { if(*bytep & 1) src_higher = 1; if(*bytep & 4) dst_higher = 1; bytep++; ins_size++; } if(*bytep != 0x0f) return 0; bytep++; ins_size++; /* Two SSSE3 instruction prefixes. */ if((*bytep == 0x38 && bytep[1] != 0x0f) || (*bytep == 0x3a && bytep[1] == 0x0f)) { uint8_t opcode = bytep[1]; uint8_t *modrm = &bytep[2]; unsigned char imm; ins_size += 2; // not counting modRM byte or anything after. if (opcode == 0x0f) { if ((bytep[2] > 0x3F) && (bytep[2] < 0x80)) { imm = bytep[4]; // modrm offset + 2 } else if ((bytep[2] > 0x7F) && (bytep[2] < 0xC0)) { imm = bytep[7]; // modrm offset + 5 } else { imm = bytep[3]; // modrm offset + 1 } } if(is_128) { int consumed = fetchoperands(modrm, src_higher, dst_higher, &xmmsrc, &xmmdst, longmode, state, kernel_trap, 1, ins_size); ins_size += consumed; switch(opcode) { case 0x00: //pshufb128(&xmmsrc,&xmmdst,&xmmres); break; xmmres.i = ssp_shuffle_epi8_SSSE3 (xmmdst.i, xmmsrc.i); break; case 0x01: //phaddw128(&xmmsrc,&xmmdst,&xmmres); break; xmmres.i = ssp_hadd_epi16_SSSE3 (xmmdst.i, xmmsrc.i); break; case 0x02: //phaddd128(&xmmsrc,&xmmdst,&xmmres); break; xmmres.i = ssp_hadd_epi32_SSSE3 (xmmdst.i, xmmsrc.i); break; case 0x03: //phaddsw128(&xmmsrc,&xmmdst,&xmmres); break; xmmres.i = ssp_hadds_epi16_SSSE3 (xmmdst.i, xmmsrc.i); break; case 0x04: //pmaddubsw128(&xmmsrc,&xmmdst,&xmmres); break; xmmres.i = ssp_maddubs_epi16_SSSE3 (xmmdst.i, xmmsrc.i); break; case 0x05: //phsubw128(&xmmsrc,&xmmdst,&xmmres); break; xmmres.i = ssp_hsub_epi16_SSSE3 (xmmdst.i, xmmsrc.i); break; case 0x06: //phsubd128(&xmmsrc,&xmmdst,&xmmres); break; xmmres.i = ssp_hsub_epi32_SSSE3 (xmmdst.i, xmmsrc.i); break; case 0x07: //phsubsw128(&xmmsrc,&xmmdst,&xmmres); break; xmmres.i = ssp_hsubs_epi16_SSSE3 (xmmdst.i, xmmsrc.i); break; case 0x08: //psignb128(&xmmsrc,&xmmdst,&xmmres); break; xmmres.i = ssp_sign_epi8_SSSE3 (xmmdst.i, xmmsrc.i); break; case 0x09: //psignw128(&xmmsrc,&xmmdst,&xmmres); break; xmmres.i = ssp_sign_epi16_SSSE3 (xmmdst.i, xmmsrc.i); break; case 0x0A: //psignd128(&xmmsrc,&xmmdst,&xmmres); break; xmmres.i = ssp_sign_epi32_SSSE3 (xmmdst.i, xmmsrc.i); break; case 0x0B: //pmulhrsw128(&xmmsrc,&xmmdst,&xmmres); break; xmmres.i = ssp_mulhrs_epi16_SSSE3 (xmmdst.i, xmmsrc.i); break; case 0x0F: //palignr128(&xmmsrc,&xmmdst,&xmmres,imm); ins_size++; break; xmmres.i = ssp_alignr_epi8_SSSE3 (xmmdst.i, xmmsrc.i, imm); ins_size++; break; case 0x1C: //pabsb128(&xmmsrc,&xmmres); break; xmmres.i = ssp_abs_epi8_SSSE3 (xmmsrc.i); break; case 0x1D: //pabsw128(&xmmsrc,&xmmres); break; xmmres.i = ssp_abs_epi16_SSSE3 (xmmsrc.i); break; case 0x1E: //pabsd128(&xmmsrc,&xmmres); break; xmmres.i = ssp_abs_epi32_SSSE3 (xmmsrc.i); break; default: return 0; } storeresult128(*modrm, dst_higher, xmmres); } else { int consumed = fetchoperands(modrm, src_higher, dst_higher, &mmsrc, &mmdst, longmode, state, kernel_trap, 0, ins_size); ins_size += consumed; switch(opcode) { case 0x00: //pshufb64(&mmsrc,&mmdst,&mmres); break; mmres.m64 = ssp_shuffle_pi8_SSSE3 (mmdst.m64, mmsrc.m64); break; case 0x01: //phaddw64(&mmsrc,&mmdst,&mmres); break; mmres.m64 = ssp_hadd_pi16_SSSE3 (mmdst.m64, mmsrc.m64); break; case 0x02: //phaddd64(&mmsrc,&mmdst,&mmres); break; mmres.m64 = ssp_hadd_pi32_SSSE3 (mmdst.m64, mmsrc.m64); break; case 0x03: //phaddsw64(&mmsrc,&mmdst,&mmres); break; mmres.m64 = ssp_hadds_pi16_SSSE3 (mmdst.m64, mmsrc.m64); break; case 0x04: //pmaddubsw64(&mmsrc,&mmdst,&mmres); break; mmres.m64 = ssp_maddubs_pi16_SSSE3 (mmdst.m64, mmsrc.m64); break; case 0x05: //phsubw64(&mmsrc,&mmdst,&mmres); break; mmres.m64 = ssp_hsub_pi16_SSSE3 (mmdst.m64, mmsrc.m64); break; case 0x06: //phsubd64(&mmsrc,&mmdst,&mmres); break; mmres.m64 = ssp_hsub_pi32_SSSE3 (mmdst.m64, mmsrc.m64); break; case 0x07: //phsubsw64(&mmsrc,&mmdst,&mmres); break; mmres.m64 = ssp_hsubs_pi16_SSSE3 (mmdst.m64, mmsrc.m64); break; case 0x08: //psignb64(&mmsrc,&mmdst,&mmres); break; mmres.m64 = ssp_sign_pi8_SSSE3 (mmdst.m64, mmsrc.m64); break; case 0x09: //psignw64(&mmsrc,&mmdst,&mmres); break; mmres.m64 = ssp_sign_pi16_SSSE3 (mmdst.m64, mmsrc.m64); break; case 0x0A: //psignd64(&mmsrc,&mmdst,&mmres); break; mmres.m64 = ssp_sign_pi32_SSSE3 (mmdst.m64, mmsrc.m64); break; case 0x0B: //pmulhrsw64(&mmsrc,&mmdst,&mmres); break; mmres.m64 = ssp_mulhrs_pi16_SSSE3 (mmdst.m64, mmsrc.m64); break; case 0x0F: //palignr64(&mmsrc,&mmdst,&mmres, imm); ins_size++; break; mmres.m64 = ssp_alignr_pi8_SSSE3 (mmdst.m64, mmsrc.m64, imm); ins_size++; break; case 0x1C: //pabsb64(&mmsrc,&mmres); break; mmres.m64 = ssp_abs_pi8_SSSE3 (mmsrc.m64); break; case 0x1D: //pabsw64(&mmsrc,&mmres); break; mmres.m64 = ssp_abs_pi16_SSSE3 (mmsrc.m64); break; case 0x1E: //pabsd64(&mmsrc,&mmres); break; mmres.m64 = ssp_abs_pi32_SSSE3 (mmsrc.m64); break; default: return 0; } storeresult64(*modrm, dst_higher, mmres); } } else { // opcode wasn't handled here return 0; } return ins_size; } int fetchoperands(uint8_t *ModRM, unsigned int hsrc, unsigned int hdst, void *src, void *dst, unsigned int longmode, x86_saved_state_t *saved_state, int kernel_trap, int size_128, int ins_size) { unsigned int num_src = *ModRM & 0x7; unsigned int num_dst = (*ModRM >> 3) & 0x7; unsigned int mod = *ModRM >> 6; int consumed = 1; //modrm + 1 byte if(hsrc) num_src += 8; if(hdst) num_dst += 8; if(size_128) getxmm((ssp_m128*)dst, num_dst); else getmm((ssp_m64*)dst, num_dst); if(mod == 3) { if(size_128) getxmm((ssp_m128*)src, num_src); else getmm((ssp_m64*)src, num_src); } // AnV - Implemented 64-bit fetch else if ((longmode = is_saved_state64(saved_state))) { uint64_t address; // DST is always an XMM register. decode for SRC. x86_saved_state64_t *r64 = saved_state64(saved_state); __uint64_t reg_sel[8] = {r64->rax, r64->rcx, r64->rdx, r64->rbx, r64->isf.rsp, r64->rbp, r64->rsi, r64->rdi}; if(hsrc) printf("opemu error: high reg ssse\n"); // FIXME if(num_src == 4) { // Special case: SIB byte used TODO fix r8-r15? uint8_t scale = ModRM[1] >> 6; uint8_t base = ModRM[1] & 0x7; uint8_t index = (ModRM[1] >> 3) & 0x7; consumed++; //modrm mode 2 // meaning of SIB depends on mod if(mod == 0) { if(base == 5) printf("opemu error: mod0 disp32 not implemented\n"); // FIXME if(index == 4) address = reg_sel[base]; else address = reg_sel[base] + (reg_sel[index] * (1<<scale)); } else { if(index == 4) address = reg_sel[base]; else address = reg_sel[base] + (reg_sel[index] * (1<<scale)); } } else { address = reg_sel[num_src]; } if((mod == 0) && (num_src == 5)) { // RIP-relative dword displacement // AnV - Warning from cast alignment fix __uint64_t ModRMVal = (__uint64_t)&ModRM[consumed]; __int32_t *ModRMCast = (__int32_t *)ModRMVal; address = *(uint32_t*)&r64->isf.rip + *ModRMCast; consumed += 4; //printf("opemu adress rip: %llu \n",address); } if(mod == 1) { // byte displacement address +=(int8_t)ModRM[consumed]; consumed++; //printf("opemu adress byte : %llu \n",address); } else if(mod ==2 ) { // dword displacement. can it be qword? // AnV - Warning from cast alignment fix __uint64_t ModRMVal = (__uint64_t)&ModRM[consumed]; __int32_t *ModRMCast = (__int32_t *)ModRMVal; address += *ModRMCast; consumed += 4; //printf("opemu adress byte : %llu \n",address); } // address is good now, do read and store operands. if(kernel_trap) { if(size_128) ((ssp_m128*)src)->ui = *(__uint128_t *)address; else ((ssp_m64*)src)->u64 = *(uint64_t *)address; } else { //printf("xnu: da = %llx, rsp=%llx, rip=%llx\n", address, reg_sel[4], r64->isf.rip); if(size_128) copyin(address, (char*)& ((ssp_m128*)src)->ui, 16); else copyin(address, (char*)& ((ssp_m64*)src)->u64, 8); } } // AnV - Implemented 32-bit fetch else { uint32_t address; // DST is always an XMM register. decode for SRC. x86_saved_state32_t* r32 = saved_state32(saved_state); uint32_t reg_sel[8] = {r32->eax, r32->ecx, r32->edx, r32->ebx, r32->uesp, r32->ebp, r32->esi, r32->edi}; if(hsrc) printf("opemu error: high reg ssse\n"); // FIXME if(num_src == 4) { /* Special case: SIB byte used TODO fix r8-r15? */ uint8_t scale = ModRM[1] >> 6; uint8_t base = ModRM[1] & 0x7; uint8_t index = (ModRM[1] >> 3) & 0x7; consumed++; // meaning of SIB depends on mod if(mod == 0) { if(base == 5) printf("opemu error: mod0 disp32 not implemented\n"); // FIXME if(index == 4) address = reg_sel[base]; else address = reg_sel[base] + (reg_sel[index] * (1<<scale)); } else { if(index == 4) address = reg_sel[base]; else address = reg_sel[base] + (reg_sel[index] * (1<<scale)); } } else { address = reg_sel[num_src]; } if((mod == 0) && (num_src == 5)) { // RIP-relative dword displacement // AnV - Warning from cast alignment fix uint64_t ModRMVal = (uint64_t)&ModRM[consumed]; int32_t *ModRMCast = (int32_t *)ModRMVal; address = r32->eip + *ModRMCast; consumed += 4; //address = r32->eip + *((int32_t*)&ModRM[consumed]); } if(mod == 1) { // byte displacement //int32_t mods = (int32_t)ModRM[consumed]; //int8_t *Mods = (int8_t*)&mods; address += (int8_t)ModRM[consumed]; consumed++; // printf("opemu adress byte : %llu \n",address); } else if(mod == 2) { // dword displacement. can it be qword? // AnV - Warning from cast alignment fix uint64_t ModRMVal = (uint64_t)&ModRM[consumed]; int32_t *ModRMCast = (int32_t *)ModRMVal; address += *ModRMCast; consumed += 4; //address += *((int32_t*)&ModRM[consumed]); } // address is good now, do read and store operands. uint64_t addr = address; if(kernel_trap) { if(size_128) ((ssp_m128*)src)->ui = *(__uint128_t *)addr; else ((ssp_m64*)src)->u64 = *(uint64_t *)addr; } else { //printf("xnu: da = %llx, rsp=%llx, rip=%llx\n", address, reg_sel[4], r32->eip); if(size_128) copyin(addr, (char*) &((ssp_m128*)src)->ui, 16); else copyin(addr, (char*) &((ssp_m64*)src)->u64, 8); } } return consumed; } void storeresult128(uint8_t ModRM, unsigned int hdst, ssp_m128 res) { unsigned int num_dst = (ModRM >> 3) & 0x7; if(hdst) num_dst += 8; movxmm(&res, num_dst); } void storeresult64(uint8_t ModRM, unsigned int __unused hdst, ssp_m64 res) { unsigned int num_dst = (ModRM >> 3) & 0x7; movmm(&res, num_dst); } /* get value from the xmm register i */ void getxmm(ssp_m128 *v, unsigned int i) { switch(i) { case 0: asm __volatile__ ("movdqu %%xmm0, %0" : "=m" (*v->s8)); break; case 1: asm __volatile__ ("movdqu %%xmm1, %0" : "=m" (*v->s8)); break; case 2: asm __volatile__ ("movdqu %%xmm2, %0" : "=m" (*v->s8)); break; case 3: asm __volatile__ ("movdqu %%xmm3, %0" : "=m" (*v->s8)); break; case 4: asm __volatile__ ("movdqu %%xmm4, %0" : "=m" (*v->s8)); break; case 5: asm __volatile__ ("movdqu %%xmm5, %0" : "=m" (*v->s8)); break; case 6: asm __volatile__ ("movdqu %%xmm6, %0" : "=m" (*v->s8)); break; case 7: asm __volatile__ ("movdqu %%xmm7, %0" : "=m" (*v->s8)); break; #ifdef __x86_64__ case 8: asm __volatile__ ("movdqu %%xmm8, %0" : "=m" (*v->s8)); break; case 9: asm __volatile__ ("movdqu %%xmm9, %0" : "=m" (*v->s8)); break; case 10: asm __volatile__ ("movdqu %%xmm10, %0" : "=m" (*v->s8)); break; case 11: asm __volatile__ ("movdqu %%xmm11, %0" : "=m" (*v->s8)); break; case 12: asm __volatile__ ("movdqu %%xmm12, %0" : "=m" (*v->s8)); break; case 13: asm __volatile__ ("movdqu %%xmm13, %0" : "=m" (*v->s8)); break; case 14: asm __volatile__ ("movdqu %%xmm14, %0" : "=m" (*v->s8)); break; case 15: asm __volatile__ ("movdqu %%xmm15, %0" : "=m" (*v->s8)); break; #endif } } /* get value from the mm register i */ void getmm(ssp_m64 *v, unsigned int i) { switch(i) { case 0: asm __volatile__ ("movq %%mm0, %0" : "=m" (*v->s8)); break; case 1: asm __volatile__ ("movq %%mm1, %0" : "=m" (*v->s8)); break; case 2: asm __volatile__ ("movq %%mm2, %0" : "=m" (*v->s8)); break; case 3: asm __volatile__ ("movq %%mm3, %0" : "=m" (*v->s8)); break; case 4: asm __volatile__ ("movq %%mm4, %0" : "=m" (*v->s8)); break; case 5: asm __volatile__ ("movq %%mm5, %0" : "=m" (*v->s8)); break; case 6: asm __volatile__ ("movq %%mm6, %0" : "=m" (*v->s8)); break; case 7: asm __volatile__ ("movq %%mm7, %0" : "=m" (*v->s8)); break; } } /* move value over to xmm register i */ void movxmm(ssp_m128 *v, unsigned int i) { switch(i) { case 0: asm __volatile__ ("movdqu %0, %%xmm0" :: "m" (*v->s8) ); break; case 1: asm __volatile__ ("movdqu %0, %%xmm1" :: "m" (*v->s8) ); break; case 2: asm __volatile__ ("movdqu %0, %%xmm2" :: "m" (*v->s8) ); break; case 3: asm __volatile__ ("movdqu %0, %%xmm3" :: "m" (*v->s8) ); break; case 4: asm __volatile__ ("movdqu %0, %%xmm4" :: "m" (*v->s8) ); break; case 5: asm __volatile__ ("movdqu %0, %%xmm5" :: "m" (*v->s8) ); break; case 6: asm __volatile__ ("movdqu %0, %%xmm6" :: "m" (*v->s8) ); break; case 7: asm __volatile__ ("movdqu %0, %%xmm7" :: "m" (*v->s8) ); break; #ifdef __x86_64__ case 8: asm __volatile__ ("movdqu %0, %%xmm8" :: "m" (*v->s8) ); break; case 9: asm __volatile__ ("movdqu %0, %%xmm9" :: "m" (*v->s8) ); break; case 10: asm __volatile__ ("movdqu %0, %%xmm10" :: "m" (*v->s8) ); break; case 11: asm __volatile__ ("movdqu %0, %%xmm11" :: "m" (*v->s8) ); break; case 12: asm __volatile__ ("movdqu %0, %%xmm12" :: "m" (*v->s8) ); break; case 13: asm __volatile__ ("movdqu %0, %%xmm13" :: "m" (*v->s8) ); break; case 14: asm __volatile__ ("movdqu %0, %%xmm14" :: "m" (*v->s8) ); break; case 15: asm __volatile__ ("movdqu %0, %%xmm15" :: "m" (*v->s8) ); break; #endif } } /* move value over to mm register i */ void movmm(ssp_m64 *v, unsigned int i) { switch(i) { case 0: asm __volatile__ ("movq %0, %%mm0" :: "m" (*v->s8) ); break; case 1: asm __volatile__ ("movq %0, %%mm1" :: "m" (*v->s8) ); break; case 2: asm __volatile__ ("movq %0, %%mm2" :: "m" (*v->s8) ); break; case 3: asm __volatile__ ("movq %0, %%mm3" :: "m" (*v->s8) ); break; case 4: asm __volatile__ ("movq %0, %%mm4" :: "m" (*v->s8) ); break; case 5: asm __volatile__ ("movq %0, %%mm5" :: "m" (*v->s8) ); break; case 6: asm __volatile__ ("movq %0, %%mm6" :: "m" (*v->s8) ); break; case 7: asm __volatile__ ("movq %0, %%mm7" :: "m" (*v->s8) ); break; } } |
|
[求助]請教關於SSSE3 指令集操作碼問題
intel的手册 蠻複雜的 我有看了 那個表有空再研究吧... 所以opcode 後面那一個byte 就是 modrm byte 就是了 但是我用IDA Pro 看 他只有1個byte的大小 0x00 - 0xff 英文版還要翻譯 才看得懂 我目前理解的是 0x00 - 0x3f 是 mod 00 0x40 - 0x7f 是 mod 01 0x80 - 0xbf 是 mod 10 0xc0 - 0xff 是 mod 11 我現在只想研究SSSE3 部分 全部參在一起看我會亂掉 現在想知道的是 SSSE3 m128 跟 m64 都會有 mod 這4種尋址方式的模式嗎 暫存器 8-15 不是m128才有在用 在modrm byte 那個字節範圍是m128 用的xmm 8 - xmm15 THX |
操作理由
RANk
{{ user_info.golds == '' ? 0 : user_info.golds }}
雪币
{{ experience }}
课程经验
{{ score }}
学习收益
{{study_duration_fmt}}
学习时长
基本信息
荣誉称号:
{{ honorary_title }}
能力排名:
No.{{ rank_num }}
等 级:
LV{{ rank_lv-100 }}
活跃值:
在线值:
浏览人数:{{ visits }}
最近活跃:{{ last_active_time }}
注册时间:{{ user_info.create_date_jsonfmt }}
勋章
兑换勋章
证书
证书查询 >
能力值