Skip to content

Commit

Permalink
add device info to registers exception
Browse files Browse the repository at this point in the history
  • Loading branch information
skylot committed Aug 30, 2023
1 parent fc46c22 commit 3405070
Show file tree
Hide file tree
Showing 4 changed files with 211 additions and 148 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -881,7 +881,9 @@ private void updateAllInfo(long threadID, long codeOffset) {
cur.regAdapter = regAdaMap.computeIfAbsent(cur.mthFullID,
k -> RegisterObserver.merge(
getRuntimeDebugInfo(cur.frame),
getSmaliRegisterList(), art));
getSmaliRegisterList(),
art,
cur.mthFullID));

if (cur.smali.getRegCount(cur.mthFullID) > 0) {
updateAllRegisters(cur.frame);
Expand Down
158 changes: 158 additions & 0 deletions jadx-gui/src/main/java/jadx/gui/device/debugger/DebugSettings.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
package jadx.gui.device.debugger;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import jadx.core.utils.StringUtils;
import jadx.gui.device.protocol.ADB;
import jadx.gui.device.protocol.ADBDevice;
import jadx.gui.utils.NLS;

public class DebugSettings {
private static final Logger LOG = LoggerFactory.getLogger(DebugSettings.class);

private static final int FORWARD_TCP_PORT = 33233;

public static final DebugSettings INSTANCE = new DebugSettings();

private int ver;
private String pid;
private String name;
private ADBDevice device;
private int forwardTcpPort = FORWARD_TCP_PORT;
private String expectPkg = "";
private boolean autoAttachPkg = false;

private DebugSettings() {
}

public void set(ADBDevice device, int ver, String pid, String name) {
this.ver = ver;
this.pid = pid;
this.name = name;
this.device = device;
this.autoAttachPkg = false;
this.expectPkg = "";
}

public DebugSettings setPid(String pid) {
this.pid = pid;
return this;
}

public DebugSettings setName(String name) {
this.name = name;
return this;
}

public String forwardJDWP() {
int localPort = forwardTcpPort;
String resultDesc = "";
try {
do {
ADBDevice.ForwardResult rst = device.forwardJDWP(localPort + "", pid);
if (rst.state == 0) {
forwardTcpPort = localPort;
return "";
}
if (rst.state == 1) {
if (rst.desc.contains("Only one usage of each socket address")) { // port is taken by other process
if (localPort < 65536) {
localPort++; // retry
continue;
}
}
}
resultDesc = rst.desc;
break;
} while (true);
} catch (Exception e) {
LOG.error("JDWP forward error", e);
}
if (StringUtils.isEmpty(resultDesc)) {
resultDesc = NLS.str("adb_dialog.forward_fail");
}
return resultDesc;
}

// we have to remove all ports that forwarding the jdwp:pid, otherwise our JDWP handshake may fail.
public void clearForward() {
String jdwpPid = " jdwp:" + pid;
String tcpPort = " tcp:" + forwardTcpPort;
try {
List<String> list = ADB.listForward(device.getDeviceInfo().getAdbHost(),
device.getDeviceInfo().getAdbPort());
for (String s : list) {
if (s.startsWith(device.getSerial()) && s.endsWith(jdwpPid) && !s.contains(tcpPort)) {
String[] fields = s.split("\\s+");
for (String field : fields) {
if (field.startsWith("tcp:")) {
try {
device.removeForward(field.substring("tcp:".length()));
} catch (Exception e) {
LOG.error("JDWP remove forward error", e);
}
}
}
}
}
} catch (Exception e) {
LOG.error("JDWP clear forward error", e);
}
}

public boolean isBeingDebugged() {
String jdwpPid = " jdwp:" + pid;
String tcpPort = " tcp:" + forwardTcpPort;
try {
List<String> list = ADB.listForward(device.getDeviceInfo().getAdbHost(),
device.getDeviceInfo().getAdbPort());
for (String s : list) {
if (s.startsWith(device.getSerial()) && s.endsWith(jdwpPid)) {
return !s.contains(tcpPort);
}
}
} catch (Exception e) {
LOG.error("ADB list forward error", e);
}
return false;
}

public int getVer() {
return ver;
}

public String getPid() {
return pid;
}

public String getName() {
return name;
}

public ADBDevice getDevice() {
return device;
}

public int getForwardTcpPort() {
return forwardTcpPort;
}

public String getExpectPkg() {
return expectPkg;
}

public void setExpectPkg(String expectPkg) {
this.expectPkg = expectPkg;
}

public boolean isAutoAttachPkg() {
return autoAttachPkg;
}

public void setAutoAttachPkg(boolean autoAttachPkg) {
this.autoAttachPkg = autoAttachPkg;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,20 @@ public class RegisterObserver {
private Map<Long, List<Info>> infoMap;
private final List<SmaliRegisterMapping> regList;
private final ArtAdapter.IArtAdapter art;
private final String mthFullID;
private boolean hasDbgInfo = false;

private RegisterObserver(ArtAdapter.IArtAdapter art) {
regList = new ArrayList<>();
infoMap = Collections.emptyMap();
private RegisterObserver(ArtAdapter.IArtAdapter art, String mthFullID) {
this.regList = new ArrayList<>();
this.infoMap = Collections.emptyMap();
this.art = art;
this.mthFullID = mthFullID;
}

@NotNull
public static RegisterObserver merge(List<RuntimeVarInfo> rtRegs, List<SmaliRegister> smaliRegs, ArtAdapter.IArtAdapter art) {
RegisterObserver adapter = new RegisterObserver(art);
public static RegisterObserver merge(List<RuntimeVarInfo> rtRegs, List<SmaliRegister> smaliRegs, ArtAdapter.IArtAdapter art,
String mthFullID) {
RegisterObserver adapter = new RegisterObserver(art, mthFullID);
adapter.hasDbgInfo = !rtRegs.isEmpty();
if (adapter.hasDbgInfo) {
adapter.infoMap = new HashMap<>();
Expand Down Expand Up @@ -93,10 +96,20 @@ private SmaliRegisterMapping getRegListEntry(int regNum) {
try {
return regList.get(regNum);
} catch (IndexOutOfBoundsException e) {
throw new RuntimeException(String.format("Register %d does not exist (%s)", regNum, art.getClass().getSimpleName()), e);
throw new RuntimeException(
String.format("Register %d does not exist (size: %d).\n %s\n Method: %s",
regNum, regList.size(), buildDeviceInfo(), mthFullID),
e);
}
}

private String buildDeviceInfo() {
DebugSettings debugSettings = DebugSettings.INSTANCE;
return "Device: " + debugSettings.getDevice().getDeviceInfo()
+ ", Android: " + debugSettings.getVer()
+ ", ArtAdapter: " + art.getClass().getSimpleName();
}

@NotNull
public List<Info> getInfoAt(long codeOffset) {
if (hasDbgInfo) {
Expand Down
Loading

0 comments on commit 3405070

Please sign in to comment.