Quero corrigir um aplicativo do tipo editor de texto em tempo de execução da seguinte maneira: quando um usuário abre qualquer arquivo, meu arquivo predefinido (digamos /tmp/predefined
) deve ser aberto em vez do arquivo original do usuário. Para essa tarefa, uso o kit de ferramentas Frida com API JavaScript. Eu intercepto todas open()
as chamadas do sistema, decido se preciso fazer uma substituição e, se for o caso, substituo o primeiro open()
parâmetro (o caminho para o arquivo a ser aberto) pelo meu predefinido.
O roteiro patcher.js
:
function main()
{
Interceptor.attach(Module.getExportByName(null, 'open'), {
onEnter(args) {
const originalPath = args[0].readCString();
if (shouldReplace(originalPath)){
args[0].writeUtf8String('/tmp/predefined'); // (1)
//args[0] = Memory.allocUtf8String("/tmp/predefined"); (2)
}
},
});
}
function shouldReplace(path) {
if (!path) return false;
// Do not replace essential system or config files:
if (path.startsWith("/usr/") || path.startsWith("/etc/") || path.startsWith("/lib") ||
path.startsWith("/var/") || path.startsWith("/proc/") || path.startsWith("/sys/") ||
path.startsWith("/dev/") || path.startsWith("/run/") || path.startsWith("/home/user/.config/")
|| path.startsWith("/home/user/.cache") || path.startsWith("/home/user/.local") ) {
return false;
}
// Avoid replacing if it's already the predefined file (prevent infinite loop)
if (path === "/tmp/predefined") {
return false;
}
// Otherwise, assume it's a user-requested file and should be repalced
return true;
}
main()
Como editor de texto, uso gnome-text-editor
o Run frida como:./frida -l patcher.js -f /usr/bin/gnome-text-editor /tmp/originalFile
Isso parece funcionar: /tmp/predefined
é aberto em vez de /tmp/originalFile
. Mas se eu quiser alocar nova memória para a string "/tmp/predefined" e atribuir um ponteiro para essa nova memória para args[0], em vez de reescrever o conteúdo da memória apontada por args[0] (descomente (2) linha, comente (1) linha), recebo erros:
- O editor não abre
/tmp/predefined
e escreveCould Not Open File You do not have permissions to open the file
- No terminal:
(gnome-text-editor:9036): editor-document-WARNING **: 11:11:33.542: Failed to load file: Error opening file /tmp/originalFile: No such file or directory
, no entanto/tmp/originalFile
existe.
Como esses erros só ocorrem quando tento alocar nova memória para uma string e alterar o valor do args[0]
ponteiro, gostaria de saber se estou usando a alocação de memória na API JavaScript do Frida corretamente?
A abordagem para substituir o buffer de caracteres
args[0]
podewriteUtf8String
ter efeitos colaterais:writeUtf8String
reutilizará o ponteiro existente e simplesmente gravará os caracteres, não importando se eles cabem no buffer ou não.args[0]
aponta para ser usado em locais diferentes dentro do programa, isso pode ter efeitos colaterais, dependendo do programa conectado ao frida.Você pode evitar isso apontando
args[0]
para uma string autoalocada. No entanto, não a aloque simplesmente dentro doonEnter
método e a retorne, pois ela será liberada pelo coletor de lixo do JavaScript no final deonEnter
.Em vez disso, você pode torná-lo uma string constante global. Este exemplo também é apresentado na página da web de melhores práticas do Frida .
Caso a string modificada a ser retornada não seja estática, você pode usar esta abordagem:
Adicioná-lo a uma matriz global preservará o buffer alocado por
Memory.allocUtf8String
para que ele não seja descartado pelo coletor de lixo JavaScript. Observe que, é claro, se o método for chamado com muita frequência, essa memória pode crescer. Portanto, essa abordagem é preferida para métodos que não são chamados com muita frequência ou em cenários em que frida não é anexado ao processo por muito tempo. Caso contrário, você pode precisar implementar algum sistema de limpeza para strings alocadas livres que não são mais usadas.