Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x86_64 RCR and RCL do not set CF flag correctly #6423

Closed
treamology opened this issue Apr 15, 2024 · 1 comment
Closed

x86_64 RCR and RCL do not set CF flag correctly #6423

treamology opened this issue Apr 15, 2024 · 1 comment
Assignees
Labels
Feature: Processor/x86 Status: Internal This is being tracked internally by the Ghidra team
Milestone

Comments

@treamology
Copy link

Describe the bug
When using the p-code emulator to run the instruction RCR RCX, 0x2, where RCX = 2, the CF flag is not set as expected. The same happens when overflow occurs on the left side when using RCL.

ROR and ROL set the flag as expected, and rotating using RCR and RCL by 1 works correctly since this is a special case in the SLEIGH.

To Reproduce

  1. Run the below RotateTest.java script.
  2. See that CF is still zero, even though it should contain the 1 that overflowed off the right.

Expected behavior
CF should be set correctly.

Environment (please complete the following information):

  • OS: Pop_OS 22.04
  • Java Version: 18.0.2-ea
  • Ghidra Version: 11.0.3
  • Ghidra Origin: Official GitHub distro

Additional context

RotateTest.java
import ghidra.app.plugin.assembler.*;
import ghidra.app.plugin.processors.sleigh.SleighLanguage;
import ghidra.app.script.GhidraScript;
import ghidra.pcode.emu.PcodeEmulator;
import ghidra.pcode.emu.PcodeThread;
import ghidra.pcode.exec.*;
import ghidra.pcode.exec.PcodeExecutorStatePiece.Reason;
import ghidra.pcode.utils.Utils;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSpace;
import ghidra.program.model.lang.LanguageID;
import ghidra.util.NumericUtilities;

public class RotateTest extends GhidraScript {
	private SleighLanguage language;
	private PcodeEmulator emulator;

	@Override
	protected void run() throws Exception {
		/*
		 * Create an emulator and start a thread
		 */
		language = (SleighLanguage) getLanguage(new LanguageID("x86:LE:64:default"));
		emulator = new PcodeEmulator(language);
		
		PcodeThread<byte[]> thread = emulator.newThread();
		// The emulator composes the full library for each thread
		PcodeUseropLibrary<byte[]> library = thread.getUseropLibrary();
		AddressSpace dyn = language.getDefaultSpace();

		/*
		 * Assemble a little test program and write it into the emulator
		 */
		Address entry = dyn.getAddress(0x00400000);
		Assembler asm = Assemblers.getAssembler(language);
		AssemblyBuffer buffer = new AssemblyBuffer(asm, entry);
		buffer.assemble("RCR RCX, 0x2");
		byte[] code = buffer.getBytes();
		println(NumericUtilities.convertBytesToString(code));
		emulator.getSharedState().setVar(dyn, entry.getOffset(), code.length, true, code);

		/*
		 * Initialize other parts of the emulator and thread state.
		 */
		PcodeProgram init = SleighProgramCompiler.compileProgram(language, "init", String.format("""
				RCX = 0x2;
				RIP = 0x%s;
				RSP = 0x00001000;
				""", entry), library);
		thread.getExecutor().execute(init, library);
		thread.overrideContextWithDefault();
		thread.reInitialize();
		
		thread.stepInstruction(1);
		
		/*
		 * Inspect the machine. You can always do this by accessing the state directly, but for
		 * anything other than simple variables, you may find compiling an expression more
		 * convenient.
		 */
		println("CF = " +
			Utils.bytesToLong(thread.getState().getVar(language.getRegister("CF"), Reason.INSPECT),
				1, language.isBigEndian()));

		println("RCX = " + Utils.bytesToLong(
			SleighProgramCompiler.compileExpression(language, "RCX").evaluate(thread.getExecutor()),
			8, language.isBigEndian()));
	}
}
@ghidracadabra ghidracadabra self-assigned this Apr 15, 2024
@ghidracadabra ghidracadabra added the Status: Triage Information is being gathered label Apr 15, 2024
@ghidracadabra ghidracadabra added Status: Internal This is being tracked internally by the Ghidra team and removed Status: Triage Information is being gathered labels May 2, 2024
@ghidracadabra
Copy link
Contributor

I can reproduce this. Should be an easy fix. Thanks for reporting it!

@ryanmkurtz ryanmkurtz added this to the 11.1 milestone May 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature: Processor/x86 Status: Internal This is being tracked internally by the Ghidra team
Projects
None yet
Development

No branches or pull requests

3 participants