// FUNCTION: Loads a segment to RAM // RETURNS: 0 if succesful // -1 if not successful due to registers size public int loadRAMfromDataArrayBytes(ref byte[] data, ref PHE headerTable) { // if data can't fit in RAM, complain and exit program if (RAM.Length < headerTable.p_filesz) { Console.WriteLine("The RAM registers size is too small. Please re-run the program with a bigger RAM memmory size"); return(-1); } else if (RAM.Length < headerTable.p_vaddr) { Console.WriteLine("The start program offset is greater than the RAM size.The RAM registers size is too small. Please re-run the program with a bigger RAM memmory size."); return(-1); } else if ((RAM.Length - headerTable.p_vaddr) < headerTable.p_filesz) { Console.WriteLine("The RAM registers size is too small. Please re-run the program with a bigger RAM memmory size"); return(-1); } else { uint i, n = 0; for (i = headerTable.p_vaddr; n < headerTable.p_filesz; i++, n++) { RAM[i] = data[n]; } return(0); } }
/// FUNCTION: Open ELF file, read elf header, read each program header entr (PHE) and store segment(s) to RAM /// if succesful elf header read, then /// - clear memory and registers /// - set programCounter with elf header entry point /// - load PHEs to RAM /// RETURNS: /// returns -1 if failed to load segments into ram /// returns 0 if success public int loadSegmentsIntoRAM(string fileName) { try { using (FileStream strm = new FileStream(fileName, FileMode.Open)) { ELF elfHeader = new ELF(); byte[] data = new byte[Marshal.SizeOf(elfHeader)]; strm.Read(data, 0, data.Length); // Read ELF header data elfHeader = ByteArrayToStructure <ELF>(data); // Convert to struct debugLog.WriteLineToLog("IMPORTANT: Debug logging information for developers: " + DateTime.Now); debugLog.WriteLineToLog("Loader: in loadSegmentsIntoRAM (): Opening " + fileName + "…"); debugLog.WriteLineToLog("Loader: in loadSegmentsIntoRAM (): Program entry address: " + elfHeader.e_entry); debugLog.WriteLineToLog("Loader: in loadSegmentsIntoRAM (): Program header offset (location in file): " + elfHeader.e_phoff); debugLog.WriteLineToLog("Loader: in loadSegmentsIntoRAM (): Size of Program header entry: " + elfHeader.e_phentsize); debugLog.WriteLineToLog("Loader: in loadSegmentsIntoRAM (): Number of segments: " + elfHeader.e_phnum); //NumberelfHeader.e_entry.ToString("X4")); // clear memory, registers, nzcv flags memory.clearMemory(); registers.clearRegisters(); registers.clearNZCVFlags(); // update program counter r15 registers.updateProgramCounter(elfHeader.e_entry); // update stack pointer r13 registers.updateStackPointer(0x7000); // Read all program header entries and load segments to RAM uint nextElfHeaderOffset = elfHeader.e_phoff; int segmentNum = 0; for (int i = 0; i < elfHeader.e_phnum; i++, segmentNum++) // Read all program headers { // Read a program header PHE headerTable = new PHE(); data = new byte[elfHeader.e_phentsize]; strm.Seek(nextElfHeaderOffset, SeekOrigin.Begin); // move position to start of next program header entry strm.Read(data, 0, (int)elfHeader.e_phentsize); // Read ELF header data headerTable = ByteArrayToStructure <PHE>(data); // Convert to struct // Load PHE to RAM strm.Seek(headerTable.p_offset, SeekOrigin.Begin); // move position to start of segment data = new byte[headerTable.p_filesz]; // resize data strm.Read(data, 0, (int)headerTable.p_filesz); // Read segment to data int succesfulLoad = memory.loadRAMfromDataArrayBytes(ref data, ref headerTable); if (succesfulLoad == -1) // return if fail to load registers, mostlikely it doesn't fit in the RAM { return(-1); } debugLog.WriteLineToLog("Loader: Segment " + segmentNum + " - vAddress = " + headerTable.p_vaddr + ", File Offset: " + headerTable.p_offset + ", Size: " + headerTable.p_filesz); nextElfHeaderOffset += ((uint)elfHeader.e_phentsize); } uint cksum = memory.ComputeRAMChecksum(null); debugLog.WriteLineToLog("\nCurrent RAM hex digest: " + cksum); //Console.WriteLine("\nCurrent RAM hex digest: " + cksum); } } catch (Exception e) { debugLog.WriteLineToLog("Loader: in loadSegmentsIntoRAM(): File cannot be opened: " + e.Message); //Console.WriteLine("For help try: armmemory.exe --help"); MessageBox.Show(e.Message, "Error Openning Executable File", MessageBoxButtons.OK, MessageBoxIcon.Error); return(-1); } return(0); }