Skip to content

Instantly share code, notes, and snippets.

@FrankSpierings
Last active June 13, 2023 14:27
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save FrankSpierings/40d03161ad706d343d416b808c8ac5d3 to your computer and use it in GitHub Desktop.
Save FrankSpierings/40d03161ad706d343d416b808c8ac5d3 to your computer and use it in GitHub Desktop.
Frida code to enumerate the Golang symbols
const utils = {
colors: {
red: function(string) {
return '\x1b[31m' + string + '\x1b[0m';
},
green: function(string) {
return '\x1b[32m' + string + '\x1b[0m';
},
yellow: function(string) {
return '\x1b[33m' + string + '\x1b[0m';
},
blue: function(string) {
return '\x1b[34m' + string + '\x1b[0m';
},
cyan: function(string) {
return '\x1b[36m' + string + '\x1b[0m';
},
},
ascii: function(address) {
var address = ptr(address);
var output = [];
for (var i=0; i<Process.pointerSize; i++) {
var b = address.shr(Process.pointerSize * i).and(0xff);
if ((b > 0x1f) && (b < 0x7f)) {
output.push(this.colors.green(String.fromCharCode(b)));
} else {
output.push(this.colors.red('.'))
}
}
return output.join('');
},
backtrace: function(context) {
return 'Backtrace:\n' + Thread.backtrace(context, Backtracer.FUZZY).map(DebugSymbol.fromAddress).join('\n') + '\n';
},
telescope: function(address) {
var items = this.addressResolve(address);
var results = [];
for (var i=0; i < items.length - 1; i++) {
var item = items[i];
var range = Process.findRangeByAddress(item['address']);
if(range) {
if (range.protection.match(/^.w.$/)) {
results.push(this.colors.blue(item['address']));
}
else if (range.protection.match(/^..x$/)) {
results.push(this.colors.red(item['address']));
}
else if (range.protection.match(/^r..$/)) {
results.push(this.colors.yellow(item['address']));
}
else {
results.push(this.colors.cyan(item['address']));
}
}
}
var output = results.join(' -> ');
output += (" = " + items[items.length - 1]['address']);
output += (": " + this.ascii(items[items.length - 1]['address']));
return output;
},
addressResolve: function(address, stack) {
address = ptr(address);
if (!stack) {
stack = [];
}
if (stack.length > 10) {
return stack;
}
var record = {
address: address,
};
try {
if (Process.pointerSize == 8) {
record['value'] = address.readU64();
} else {
record['value'] = address.readU32();
}
try {
record['string'] = address.readUtf8String();
} catch (error) {}
}
catch (error) {
// console.warn('Address ' + address + ' is not a pointer');
}
stack.push(record);
if (record['value']) {
stack = this.addressResolve(ptr(record['value']), stack);
}
return stack;
}
};
const Golang = {
gopclntab: null,
symbolmap: null,
findGopclntab: function() {
if (this.gopclntab) {
return this.gopclntab;
}
const pattern = "FB FF FF FF 00 00";
var mainmodule = Process.enumerateModules()[0];
var ranges = Process.enumerateRangesSync('r--');
for (var ri in ranges) {
var range = ranges[ri];
if (range['base'] && range['size'] &&
range['file'] && (range['file']['path'] == mainmodule['path'])) {
var matches = Memory.scanSync(range['base'], range['size'], pattern);
if (matches && matches.length > 0) {
// console.log(JSON.stringify(matches));
for (var mi in matches) {
// Check if this is the table by comparing its first entry defined
// address with the defined offset + the found address.
var address = matches[mi]['address'];
// console.log(hexdump(address));
var entry = address.add(8).add(Process.pointerSize).readPointer();
var offset = address.add(8).add(Process.pointerSize * 2).readPointer();
if (address.add(offset).readPointer().compare(entry) == 0) {
// console.log(address);
this.gopclntab = address;
return this.gopclntab;
}
};
}
}
}
return null;
},
enumerateSymbolsSync: function() {
if (this.symbolmap) {
return this.symbolmap;
}
var address = this.findGopclntab();
var output = [];
if(address) {
// Read the header
var headerSize = 8;
var tableBase = address;
var recordSize = Process.pointerSize * 2;
var cursor = address.add(headerSize);
var tableEnd = address.add(cursor.readUInt() * recordSize);
cursor = cursor.add(Process.pointerSize);
// Enumerate the records
while ((cursor.compare(tableEnd) == -1)) {
var offset = cursor.add(Process.pointerSize).readPointer();
var functionAddress = tableBase.add(offset).readPointer();
var nameOffset = tableBase.add(offset).add(Process.pointerSize).readU32();
var name = tableBase.add(nameOffset).readUtf8String();
output.push({
address: functionAddress,
name: name,
table: tableBase.add(offset),
tableBase: tableBase,
})
cursor = cursor.add(recordSize);
}
}
this.symbolmap = output;
return this.symbolmap;
},
findSymbolByName: function(name) {
var map = this.enumerateSymbolsSync();
for (var index in map) {
if (map[index]['name'] === name) {
return map[index]['address'];
}
}
return null;
},
findSymbolsByPattern: function(pattern) {
var map = this.enumerateSymbolsSync();
var output = []
for (var index in map) {
if (map[index]['name'].match(pattern)) {
output.push(map[index]);
}
}
return output;
},
};
function golanghooks() {
(function() {
var name = 'crypto/aes.NewCipher';
var address = Golang.findSymbolByName(name);
if (address != null) {
console.log('[!] Hooking: ' + name + ' @ 0x' + address.toString(16));
try {
Interceptor.attach(address, {
onEnter: function(args) {
},
onLeave: function(result) {
console.log(name);
var rsp = this.context['rsp'];
var key = hexdump(rsp.add(Process.pointerSize * 1).readPointer(), {length:32});
for (var i=0; i<4; i++) {
console.log('[' + i +'] ' + utils.telescope(rsp));
rsp = rsp.add(Process.pointerSize);
}
console.log(utils.colors.red("Key:\n" + key));
console.log(utils.colors.yellow(utils.backtrace(this.context)));
},
});
}
catch (error) {
console.error(error);
}
}
})();
(function() {
var name = 'crypto/cipher.newCFB';
var address = Golang.findSymbolByName(name);
if (address != null) {
console.log('[!] Hooking: ' + name + ' @ 0x' + address.toString(16));
try {
Interceptor.attach(address, {
onEnter: function(args) {
},
onLeave: function(result) {
console.log(name);
var rsp = this.context['rsp'];
var iv = hexdump(rsp.add(Process.pointerSize * 3).readPointer(), {length:16});
for (var i=0; i<4; i++) {
console.log('[' + i +'] ' + utils.telescope(rsp));
rsp = rsp.add(Process.pointerSize);
}
console.log(utils.colors.red("IV:\n" + iv));
console.log(utils.colors.yellow(utils.backtrace(this.context)));
},
});
}
catch (error) {
console.error(error);
}
}
})();
}
golanghooks();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment