Skip to content

Commit 5590fbc

Browse files
author
Your Name
committed
Added support for reading TLS
1 parent 19e5e8b commit 5590fbc

File tree

13 files changed

+309
-3
lines changed

13 files changed

+309
-3
lines changed

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "frida-cshell",
3-
"version": "1.8.3",
3+
"version": "1.8.4",
44
"description": "Frida's CShell",
55
"scripts": {
66
"prepare": "npm run version && npm run build && npm run package && npm run copy",

src/breakpoints/code.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { Regs } from './regs.js';
44
import { Format } from '../misc/format.js';
55
import { Var } from '../vars/var.js';
66
import { Bp, BpKind, BpType } from './bp.js';
7+
import { Tls } from '../tls/tls.js';
78

89
export abstract class BpCode extends Bp {
910
public kind: BpKind = BpKind.Code;
@@ -53,6 +54,7 @@ export abstract class BpCode extends Bp {
5354
Regs.setContext(ctx);
5455
Regs.setReturnAddress(returnAddress);
5556
Regs.setBreakpointId(this.index);
57+
Regs.setTls(Tls.getTls());
5658
if (retVal !== null) Regs.setRetVal(retVal);
5759

5860
try {

src/breakpoints/memory.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Output } from '../io/output.js';
22
import { Mem } from '../memory/mem.js';
33
import { Format } from '../misc/format.js';
4+
import { Tls } from '../tls/tls.js';
45
import { Var } from '../vars/var.js';
56
import { Bp, BpKind, BpType } from './bp.js';
67
import { Regs } from './regs.js';
@@ -94,6 +95,7 @@ export abstract class BpMemory extends Bp {
9495
Regs.setAddress(details.address);
9596
Regs.setPc(details.from);
9697
Regs.setBreakpointId(this.index);
98+
Regs.setTls(Tls.getTls());
9799

98100
try {
99101
if (this.runConditions()) {

src/breakpoints/regs.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ enum PseudoRegNames {
55
RA = 'ra',
66
ADDRESS = 'addr',
77
BP = 'bp',
8+
TLS = 'tls',
89
}
910

1011
type PseudoRegs = {
@@ -23,6 +24,7 @@ export class Regs {
2324
[PseudoRegNames.RA]: null,
2425
[PseudoRegNames.ADDRESS]: null,
2526
[PseudoRegNames.BP]: null,
27+
[PseudoRegNames.TLS]: null,
2628
};
2729

2830
private constructor() {}
@@ -60,6 +62,13 @@ export class Regs {
6062
this.pseudoRegs[PseudoRegNames.BP] = Var.fromId(breakpointId);
6163
}
6264

65+
public static setTls(tls: NativePointer) {
66+
this.pseudoRegs[PseudoRegNames.TLS] = new Var(
67+
uint64(tls.toString()),
68+
PseudoRegNames.TLS,
69+
);
70+
}
71+
6372
public static get(name: string): Var {
6473
if (name in this.pseudoRegs) {
6574
const key = name as PseudoRegNames;

src/cmdlets/development/js.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ import { EchoCmdLet } from '../misc/echo.js';
8484
import { CorpseCmdLet } from '../misc/corpse/corpse.js';
8585
import { ErrnoCmdLet } from '../misc/errno.js';
8686
import { SzCmdLet } from '../files/sz.js';
87+
import { TlsCmdLet } from '../thread/tls.js';
8788

8889
export class JsCmdLet extends CmdLetBase {
8990
name = 'js';
@@ -168,6 +169,7 @@ js path - load commandlet JS script
168169
SubCmdLet: SubCmdLet,
169170
SymCmdLet: SymCmdLet,
170171
ThreadCmdLet: ThreadCmdLet,
172+
TlsCmdLet: TlsCmdLet,
171173
TraceBlockCmdLet: TraceBlockCmdLet,
172174
TraceCallCmdLet: TraceCallCmdLet,
173175
TraceCoverageCmdLet: TraceCoverageCmdLet,

src/cmdlets/thread/tls.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { CmdLetBase } from '../../commands/cmdlet.js';
2+
import { Output } from '../../io/output.js';
3+
import { Token } from '../../io/token.js';
4+
import { Var } from '../../vars/var.js';
5+
import { Tls } from '../../tls/tls.js';
6+
7+
export class TlsCmdLet extends CmdLetBase {
8+
name = 'tls';
9+
category = 'thread';
10+
help = 'read the TLS pointer';
11+
12+
private static readonly USAGE: string = `Usage: tls
13+
tls - get the tls pointer`;
14+
15+
public runSync(tokens: Token[]): Var {
16+
if (tokens.length > 0) {
17+
Output.writeln(TlsCmdLet.USAGE);
18+
return Var.ZERO;
19+
}
20+
21+
const tls = Tls.getTls();
22+
return new Var(uint64(tls.toString()));
23+
}
24+
25+
public override isSupported(): boolean {
26+
return Tls.isSupported();
27+
}
28+
29+
public usage(): Var {
30+
Output.writeln(TlsCmdLet.USAGE);
31+
return Var.ZERO;
32+
}
33+
}

src/commands/cmdlets.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ import { EchoCmdLet } from '../cmdlets/misc/echo.js';
7171
import { CorpseCmdLet } from '../cmdlets/misc/corpse/corpse.js';
7272
import { ErrnoCmdLet } from '../cmdlets/misc/errno.js';
7373
import { SzCmdLet } from '../cmdlets/files/sz.js';
74+
import { TlsCmdLet } from '../cmdlets/thread/tls.js';
7475

7576
export class CmdLets {
7677
private static byName: Map<string, CmdLet> = new Map<string, CmdLet>();
@@ -129,6 +130,7 @@ export class CmdLets {
129130
this.registerCmdletType(SymCmdLet);
130131
this.registerCmdletType(SzCmdLet);
131132
this.registerCmdletType(ThreadCmdLet);
133+
this.registerCmdletType(TlsCmdLet);
132134
this.registerCmdletType(TraceBlockCmdLet);
133135
this.registerCmdletType(TraceCallCmdLet);
134136
this.registerCmdletType(TraceCoverageCmdLet);

src/tls/arm.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { Output } from '../io/output.js';
2+
3+
export class TlsArm {
4+
private static readonly SHELL_CODE: Uint8Array = new Uint8Array([
5+
/* mrc p15,0x0,r0,cr13,cr0,0x3 */ 0x70, 0x0f, 0x1d, 0xee, /* bx lr */ 0x1e,
6+
0xff, 0x2f, 0xe1,
7+
]);
8+
9+
public getTls(): NativePointer {
10+
const buffer = Memory.alloc(
11+
TlsArm.SHELL_CODE.length + 2 * Process.pageSize,
12+
);
13+
Output.debug(`buffer: ${buffer.toString(16)}`);
14+
const shellCode = buffer.add(Process.pageSize);
15+
Output.debug(`shellCode: ${shellCode.toString(16)}`);
16+
shellCode.writeByteArray(TlsArm.SHELL_CODE.buffer as ArrayBuffer);
17+
const fnPtr = new NativeFunction(shellCode, 'pointer', []);
18+
Memory.protect(shellCode, TlsArm.SHELL_CODE.length, 'r-x');
19+
const seg = fnPtr();
20+
Memory.protect(shellCode, TlsArm.SHELL_CODE.length, 'rw-');
21+
return seg;
22+
}
23+
24+
public static getTls(): NativePointer {
25+
const tls = new TlsArm();
26+
const ptr = tls.getTls();
27+
return ptr;
28+
}
29+
}

src/tls/arm64.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { Output } from '../io/output.js';
2+
3+
export class TlsAarch64 {
4+
private static readonly SHELL_CODE: Uint8Array = new Uint8Array([
5+
/* mrs x0, tpidr_el0 */ 0x40, 0xd0, 0x3b, 0xd5, /* ret */ 0xc0, 0x03, 0x5f,
6+
0xd6,
7+
]);
8+
9+
public getTls(): NativePointer {
10+
const buffer = Memory.alloc(
11+
TlsAarch64.SHELL_CODE.length + 2 * Process.pageSize,
12+
);
13+
Output.debug(`buffer: ${buffer.toString(16)}`);
14+
const shellCode = buffer.add(Process.pageSize);
15+
Output.debug(`shellCode: ${shellCode.toString(16)}`);
16+
shellCode.writeByteArray(TlsAarch64.SHELL_CODE.buffer as ArrayBuffer);
17+
const fnPtr = new NativeFunction(shellCode, 'pointer', []);
18+
Memory.protect(shellCode, TlsAarch64.SHELL_CODE.length, 'r-x');
19+
const seg = fnPtr();
20+
Memory.protect(shellCode, TlsAarch64.SHELL_CODE.length, 'rw-');
21+
return seg;
22+
}
23+
24+
public static getTls(): NativePointer {
25+
const tls = new TlsAarch64();
26+
const ptr = tls.getTls();
27+
return ptr;
28+
}
29+
}

0 commit comments

Comments
 (0)