【问题标题】:String replace in PerlPerl中的字符串替换
【发布时间】:2012-09-21 13:18:24
【问题描述】:

我正在尝试对代码进行去混淆处理。这段代码使用了很多长变量名,在运行代码时这些变量名被替换为有意义的名称。

如何在搜索和替换时保留状态?

例如,使用这样的混淆行:

${${"GLOBALS"}["ttxdbvdj"]}=_hash(${$urqboemtmd}.substr(${${"GLOBALS"}["wkcjeuhsnr"]},${${"GLOBALS"}["gjbhisruvsjg"]}-${$rrwbtbxgijs},${${"GLOBALS"}["ibmtmqedn"]}));

mappings.txt 中有多个映射匹配上面的混淆行,例如:

$rrwbtbxgijs = hash_length;
$urqboemtmd = out;

在第一次运行时,它将在上面的混淆行中将 $rrwbtbxgijs 替换为 hash_length。现在,当它在外部 while 循环的下一次迭代中遇到第二个映射时,它将在混淆的行中将 $urqboemtmd 替换为 out。

问题是:

当遇到第一个映射时,它会进行替换。但是,当遇到不同匹配字符串的同一行中的下一个映射时,之前的搜索/替换结果不存在。

它应该保留之前的替换。我该怎么做?

我编写了一个 Perl 脚本,它会从 mapping.txt 中选择一个映射,并在整个混淆代码中搜索该映射的所有出现,并将其替换为有意义的文本。

这是我写的代码:

#! /usr/bin/perl

use warnings;

($mapping, $input) = @ARGV;

open MAPPING, '<', $mapping
    or die "couldn't read from the file, $mapping with error: $!\n";

while (<MAPPING>) {

    chomp;
    $line = $_;
    ($key, $value) = split("=", $line);
    open INPUT, '<', $input;

    while (<INPUT>) {

        chomp;
        if (/$key/) {

            $_=~s/\Q$key/$value/g;
            print $_,"\n";
        }
    }
    close INPUT;
}
close MAPPING;

【问题讨论】:

    标签: regex string perl replace


    【解决方案1】:

    告诉 Perl 不要解释 $key 中的字符:

    s/\Q$key/$value/g
    

    【讨论】:

    • 谢谢,它有效:) 我已经更新了这个问题。您能否检查一下并提出一个好的解决方法?
    【解决方案2】:

    要匹配字符串中的文字元字符,您可以使用quotemeta 或:

    s/\Q$key\E/$replace/
    

    【讨论】:

    • 谢谢。这有效,我已经更新了我的问题。你能检查一下吗?我需要保留替换阶段。例如,它一次在一行中进行一个替换。当它在该行中发现另一个不同的映射出现时,它应该保留以前的状态。这意味着,它应该在找到匹配项时不断更新同一行。
    • @NeonFlash 我明白你说的每一个字,但不明白你的意思。 “保留替代阶段”是什么意思?我假设您的意思是您当时无法检查一个键。您可以将输入文件存储在数组中,而不是为每次迭代打开文件。最后保存打印。
    【解决方案3】:

    考虑使用B::Deobfuscate 并逐渐在其配置文件中输入变量名称,以了解它们的作用。

    我对您保存状态的请求有点困惑。你到底在做什么/你打算对输出做什么?这是一次完成所有替换的(未经测试的)示例,如果有帮助吗?

    my %map;
    while ( my $line = <MAPPING> ) {
        chomp $line;
        my ($key, $value) = split("=", $line);
        $map{$key} = $value;
    }
    close MAPPING;
    
    my $search = qr/(@{[ join '|', map quotemeta, sort { length $b <=> length $a } keys %map ]})/;
    while ( my $line = <INPUT> ) {
        $line =~ s/$search/$map{$1}/g;
        print OUTPUT $line;
    }
    

    【讨论】:

    • 嗨,这看起来确实很有用,但它非常复杂。我很想花时间学习如何有效地使用它,但是目前,有没有办法让我当前的脚本工作?它能够正确替换值,我只是希望它保留状态。一旦成功的搜索/替换完成,它应该被保存。接下来,搜索/替换操作应该对上一个的结果起作用。
    • @Neon Flash:请参阅答案中添加的示例/问题
    猜你喜欢
    • 1970-01-01
    • 2014-10-06
    • 2020-07-23
    • 2019-01-15
    • 2022-01-08
    • 2013-03-08
    • 2015-10-11
    • 2014-12-03
    • 1970-01-01
    相关资源
    最近更新 更多