天天看點

中國移動飛信的研究 筆記二

中国移动飞信的研究 笔记二

经过 上一篇 的查看飞信 里面 封装了不少。 这里面不仅是一层加一层,而且是这一层还调用另外的程序集。类与类之间的组合、继承可谓是 很复杂。到底从哪里下手呢。 我本次研究 也不是为了彻底的研究它,也就是他的一些基本功能的研究。顺便,将一些类弄清楚。最后还是按照程序的 运行顺序一步一步的来研究吧。按照功能分析。

 

声明:个人并非侵犯 移动公司的权益。此笔记纯属个人学习的记录。若移动不同意,我立马将这些文档删除!希望各位见谅!

 

下面就将程序的包含主函数的Program 发出来:

 

namespace Imps.Client.Pc

{

using System;

using System.Net;

using System.Runtime.InteropServices;

using System.Threading;

using System.Windows.Forms;

internal static class Program

{

private const int BUFSIZE = 0x3e8;

private const int TOKEN_ADJUST_PRIVILEGES = 0x20;

private const int TOKEN_QUERY = 8;

[DllImport("kernel32.dll", ExactSpelling=true)]

internal static extern IntPtr GetCurrentProcess();

[DllImport("advapi32", CharSet=CharSet.Auto)]

private static extern bool GetTokenInformation(IntPtr hToken, TOKEN_INFORMATION_CLASS tokenInfoClass, IntPtr TokenInformation, int tokeInfoLength, ref int reqLength);

[STAThread]

private static void Main(string[] args)

{

Thread.CurrentThread.Name = "Imps.Client.Pc MainThread";

Application.EnableVisualStyles();

ServicePointManager.MaxServicePointIdleTime = 0x7530;

try

{

IntPtr currentProcess = GetCurrentProcess();

IntPtr zero = IntPtr.Zero;

if (!OpenProcessToken(currentProcess, 40, ref zero))

{

goto Label_008C;

}

IntPtr tokenInformation = Marshal.AllocHGlobal(0x3e8);

int tokeInfoLength = 0x3e8;

GetTokenInformation(zero, TOKEN_INFORMATION_CLASS.TokenPrivileges, tokenInformation, tokeInfoLength, ref tokeInfoLength);

TokPriv1Luid luid = (TokPriv1Luid) Marshal.PtrToStructure(tokenInformation, typeof(TokPriv1Luid));

if (luid.Count > 1)

{

goto Label_008C;

}

MessageBox.Show("运行此程序的权限不够!");

}

catch

{

}

return;

Label_008C:

Application.SetCompatibleTextRenderingDefault(false);

Application.Run(new MainForm(args));

}

[DllImport("advapi32.dll", SetLastError=true, ExactSpelling=true)]

internal static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr phtok);

private enum TOKEN_INFORMATION_CLASS

{

TokenDefaultDacl = 6,

TokenGroups = 2,

TokenImpersonationLevel = 9,

TokenOwner = 4,

TokenPrimaryGroup = 5,

TokenPrivileges = 3,

TokenRestrictedSids = 11,

TokenSessionId = 12,

TokenSource = 7,

TokenStatistics = 10,

TokenType = 8,

TokenUser = 1

}

[StructLayout(LayoutKind.Sequential, Pack=1)]

internal struct TokPriv1Luid

{

public int Count;

public long Luid;

public int Attr;

}

}

}

  

此程序里引用了 Windows的API。

引用这些API 据我 查看应该是 保证程序有足够的 权限来运行!

由 Application.Run(new MainForm(args)); 可以看出,首先是调用了主界面 MainForm。

其中,args 为传递过来的参数。

下面是 MainForm的源代码: 由于程序源代码多大 3200多行,IE打开会很慢,所以只列出重要代码!

namespace Imps.Client.Pc

{

using Imps.Client;

using Imps.Client.Base;

using Imps.Client.CommLayer;

using Imps.Client.Core;

using Imps.Client.Logger;

using Imps.Client.Pc.BizControls;

using Imps.Client.Pc.MessageHistory2;

using Imps.Client.Pc.Options;

using Imps.Client.Pc.Sensor;

using Imps.Client.Pc.Theme;

using Imps.Client.Pc.UIContactList;

using Imps.Client.Pc.UserAccount;

using Imps.Client.Resource;

using Imps.Client.Utils;

using Imps.Client.Utils.sensmon;

using Imps.Client.Utils.Win32;

using Imps.Common;

using Imps.Utils;

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Diagnostics;

using System.Drawing;

using System.IO;

using System.Runtime.CompilerServices;

using System.Runtime.InteropServices;

using System.Text;

using System.Threading;

using System.Windows.Forms;

using System.Xml;

public class MainForm : EForm, IFrameworkWindow

{

...

...

public event EventHandler BeginSuspend;

public event PositionEventHandler HideAdvChanel;

public event EventHandler MainWindowLoaded;

public event EventHandler SuspendRestored;

static MainForm()

{

int[] numArray = new int[3];

numArray[1] = 0x579;

numArray[2] = 0x57c;

UserError = numArray;

}

public MainForm() : this(new string[0])

{

}

public MainForm(string[] args)

{

this._syncObjSensor = new object();

this.WM_FETIONSTARTED = (int) Imps.Client.Utils.Win32.NativeMethods.RegisterWindowMessage("FetionStarted");

CallMe.InitCallMe(this);

CallMeHelper.WM_FETION_CALLME = (int) Imps.Client.Utils.Win32.NativeMethods.RegisterWindowMessage("FetionCallMeMessage");

if (this.TryCheckSingleton())

{

CallMeHelper.TrySendCallMeMessage(args, base.Handle);

Environment.Exit(0);

}

else

{

if (this.ExistFetionInstance())

{

if (CallMeHelper.TrySendCallMeMessage(args, base.Handle))

{

Environment.Exit(0);

return;

}

}

else if (args.Length >= 1)

{

foreach (string str in args)

{

if (CallMe.ParseCallMeParams(str) == 0)

{

break;

}

}

}

try

{

this.HandleExceptions();

this.InitLogger();

this.ParseArgs(args);

this.InitializeComponent();

this.trayIcon.Icon = ImpsTrayIcons.OffLine;

base.Icon = ImpsIcons.Logo;

FuncDispatcher.SetMainWindow(this);

this.BuildMainMenu();

this.InitUiComponents();

this.InitMainUIForm(this);

this.trayIcon.Visible = true;

this.DoLocalization();

this.RearrangeUiElements();

this.TryLoadWindowsSetting(this);

if (!this.CurrentUser.Configuration.UserSetting.MainWindowSetting.AutoPopup)

{

base.WindowState = FormWindowState.Minimized;

if (UserAccounts.LatestAccountAutoLogin)

{

base.ShowInTaskbar = false;

}

}

ImpsHelp.HelpPage = Imps.Client.Core.FixedClientSetting.Instance.HelpPage;

this.CurHandleRef = new HandleRef(this, base.Handle);

this.RegWndMsg();

}

catch (Exception exception)

{

MessageBox.Show(exception.Message);

ShellHelper.ApplicationExit();

}

}

}

...

...

}

}

 

            if (this.TryCheckSingleton())

            {

                CallMeHelper.TrySendCallMeMessage(args, base.Handle);

                Environment.Exit(0);

            }

            else

            {

                if (this.ExistFetionInstance())

                {

                    if (CallMeHelper.TrySendCallMeMessage(args, base.Handle))

                    {

                        Environment.Exit(0);

                        return;

                    }

                }

这里可以看出 飞信程序一台机器只能登陆一个。保证了程序的唯一性。

 

由于主界面里功能很复杂,篇幅太长这里就不解释了。

 

繼續閱讀