| 156 | } |
| 157 | |
| 158 | void CNodeFunction::DisassembleBytes( ULONG_PTR Address ) |
| 159 | { |
| 160 | ULONG_PTR StartAddress = Address; |
| 161 | UCHAR Code[2048] = { 0xCC }; // set max function size to 2048 bytes |
| 162 | UIntPtr EndCode = (UIntPtr)(Code + 2048); |
| 163 | |
| 164 | // Clear old disassembly info |
| 165 | if (m_pEdit) |
| 166 | { |
| 167 | m_pEdit->SetReadOnly( FALSE ); |
| 168 | m_pEdit->Clear( ); |
| 169 | m_pEdit->SetReadOnly( TRUE ); |
| 170 | } |
| 171 | m_Assembly.clear( ); |
| 172 | m_dwMemorySize = 0; |
| 173 | m_nLongestLine = 0; |
| 174 | |
| 175 | // Read in process bytes |
| 176 | if (ReClassReadMemory( (LPVOID)StartAddress, (LPVOID)Code, 2048, NULL ) == TRUE) |
| 177 | { |
| 178 | DISASM MyDisasm; |
| 179 | BOOLEAN Error = FALSE; |
| 180 | |
| 181 | ZeroMemory( &MyDisasm, sizeof( DISASM ) ); |
| 182 | MyDisasm.EIP = (UIntPtr)Code; |
| 183 | MyDisasm.VirtualAddr = (UInt64)StartAddress; |
| 184 | #ifdef _WIN64 |
| 185 | MyDisasm.Archi = 64; |
| 186 | #else |
| 187 | MyDisasm.Archi = 0; |
| 188 | #endif |
| 189 | MyDisasm.Options = NasmSyntax | PrefixedNumeral | ShowSegmentRegs; |
| 190 | |
| 191 | // Get assembly lines |
| 192 | while (Error == FALSE) |
| 193 | { |
| 194 | int disasmLen = 0; |
| 195 | |
| 196 | MyDisasm.SecurityBlock = (UInt32)(EndCode - MyDisasm.EIP); |
| 197 | |
| 198 | disasmLen = Disasm( &MyDisasm ); |
| 199 | if (disasmLen == OUT_OF_BLOCK || disasmLen == UNKNOWN_OPCODE) |
| 200 | { |
| 201 | Error = TRUE; |
| 202 | } |
| 203 | else |
| 204 | { |
| 205 | CHAR szInstruction[256] = { 0 }; |
| 206 | CHAR szBytes[128] = { 0 }; |
| 207 | |
| 208 | // INT3 instruction usually indicates the end of a function (obviously this is temporary) |
| 209 | if (MyDisasm.Instruction.Opcode == 0xCC) |
| 210 | break; |
| 211 | |
| 212 | // Generate instruction bytes |
| 213 | for (int i = 0; i < disasmLen; i++) |
| 214 | { |
| 215 | sprintf_s( szBytes + (i * 3), 4, "%02X ", *(UCHAR*)(MyDisasm.EIP + i) ); |
nothing calls this directly
no test coverage detected