Browse Source

使用C#实现自动获取Token

SwaggyMacro 1 year ago
parent
commit
3cc95dc88c

+ 1 - 7
SheepSheep/Form1.cs

@@ -30,16 +30,10 @@ namespace SheepSheep
             getWechatToken();
         }
 
-        [DllImport("GetTokenFromWechat.dll")]
-        static extern IntPtr GetTokenFromWechat();
 
         private void getWechatToken() {
             string token = "";
-            try
-            {
-                token = Marshal.PtrToStringAnsi(GetTokenFromWechat());
-            }
-            catch { }
+            token = WcToken.GetTokenFromWechat();
             if (token.Equals("false"))
             {
                 MessageBox.Show(this, "未检测到\"微信->羊了个羊\",请重新登陆微信并打开羊了个羊游戏。\n仍然显示此提示的话请自行抓包获取Token。", "Tips:", MessageBoxButtons.OK, MessageBoxIcon.Warning);

+ 0 - 9
SheepSheep/Program.cs

@@ -15,18 +15,9 @@ namespace SheepSheep
         [STAThread]
         static void Main()
         {
-            releaseDLL();
             Application.EnableVisualStyles();
             Application.SetCompatibleTextRenderingDefault(false);
             Application.Run(new Form1());
         }
-
-        private static void releaseDLL() {
-            byte[] dll = global::SheepSheep.Properties.Resources.GetTokenFromWechat;
-            string path = Application.StartupPath + @"\GetTokenFromWechat.dll";
-            using (FileStream fs = new FileStream(path, FileMode.Create)) {
-                fs.Write(dll, 0, dll.Length);
-            }
-        }
     }
 }

+ 0 - 73
SheepSheep/Properties/Resources.Designer.cs

@@ -1,73 +0,0 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     此代码由工具生成。
-//     运行时版本:4.0.30319.42000
-//
-//     对此文件的更改可能会导致不正确的行为,并且如果
-//     重新生成代码,这些更改将会丢失。
-// </auto-generated>
-//------------------------------------------------------------------------------
-
-namespace SheepSheep.Properties {
-    using System;
-    
-    
-    /// <summary>
-    ///   一个强类型的资源类,用于查找本地化的字符串等。
-    /// </summary>
-    // 此类是由 StronglyTypedResourceBuilder
-    // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
-    // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
-    // (以 /str 作为命令选项),或重新生成 VS 项目。
-    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
-    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
-    internal class Resources {
-        
-        private static global::System.Resources.ResourceManager resourceMan;
-        
-        private static global::System.Globalization.CultureInfo resourceCulture;
-        
-        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
-        internal Resources() {
-        }
-        
-        /// <summary>
-        ///   返回此类使用的缓存的 ResourceManager 实例。
-        /// </summary>
-        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
-        internal static global::System.Resources.ResourceManager ResourceManager {
-            get {
-                if (object.ReferenceEquals(resourceMan, null)) {
-                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SheepSheep.Properties.Resources", typeof(Resources).Assembly);
-                    resourceMan = temp;
-                }
-                return resourceMan;
-            }
-        }
-        
-        /// <summary>
-        ///   重写当前线程的 CurrentUICulture 属性,对
-        ///   使用此强类型资源类的所有资源查找执行重写。
-        /// </summary>
-        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
-        internal static global::System.Globalization.CultureInfo Culture {
-            get {
-                return resourceCulture;
-            }
-            set {
-                resourceCulture = value;
-            }
-        }
-        
-        /// <summary>
-        ///   查找 System.Byte[] 类型的本地化资源。
-        /// </summary>
-        internal static byte[] GetTokenFromWechat {
-            get {
-                object obj = ResourceManager.GetObject("GetTokenFromWechat", resourceCulture);
-                return ((byte[])(obj));
-            }
-        }
-    }
-}

+ 0 - 124
SheepSheep/Properties/Resources.resx

@@ -1,124 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<root>
-  <!-- 
-    Microsoft ResX Schema 
-    
-    Version 2.0
-    
-    The primary goals of this format is to allow a simple XML format 
-    that is mostly human readable. The generation and parsing of the 
-    various data types are done through the TypeConverter classes 
-    associated with the data types.
-    
-    Example:
-    
-    ... ado.net/XML headers & schema ...
-    <resheader name="resmimetype">text/microsoft-resx</resheader>
-    <resheader name="version">2.0</resheader>
-    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
-    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
-    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
-    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
-    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
-        <value>[base64 mime encoded serialized .NET Framework object]</value>
-    </data>
-    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
-        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
-        <comment>This is a comment</comment>
-    </data>
-                
-    There are any number of "resheader" rows that contain simple 
-    name/value pairs.
-    
-    Each data row contains a name, and value. The row also contains a 
-    type or mimetype. Type corresponds to a .NET class that support 
-    text/value conversion through the TypeConverter architecture. 
-    Classes that don't support this are serialized and stored with the 
-    mimetype set.
-    
-    The mimetype is used for serialized objects, and tells the 
-    ResXResourceReader how to depersist the object. This is currently not 
-    extensible. For a given mimetype the value must be set accordingly:
-    
-    Note - application/x-microsoft.net.object.binary.base64 is the format 
-    that the ResXResourceWriter will generate, however the reader can 
-    read any of the formats listed below.
-    
-    mimetype: application/x-microsoft.net.object.binary.base64
-    value   : The object must be serialized with 
-            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
-            : and then encoded with base64 encoding.
-    
-    mimetype: application/x-microsoft.net.object.soap.base64
-    value   : The object must be serialized with 
-            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
-            : and then encoded with base64 encoding.
-
-    mimetype: application/x-microsoft.net.object.bytearray.base64
-    value   : The object must be serialized into a byte array 
-            : using a System.ComponentModel.TypeConverter
-            : and then encoded with base64 encoding.
-    -->
-  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
-    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
-    <xsd:element name="root" msdata:IsDataSet="true">
-      <xsd:complexType>
-        <xsd:choice maxOccurs="unbounded">
-          <xsd:element name="metadata">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" />
-              </xsd:sequence>
-              <xsd:attribute name="name" use="required" type="xsd:string" />
-              <xsd:attribute name="type" type="xsd:string" />
-              <xsd:attribute name="mimetype" type="xsd:string" />
-              <xsd:attribute ref="xml:space" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="assembly">
-            <xsd:complexType>
-              <xsd:attribute name="alias" type="xsd:string" />
-              <xsd:attribute name="name" type="xsd:string" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="data">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
-                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
-              </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
-              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
-              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
-              <xsd:attribute ref="xml:space" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="resheader">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
-              </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" use="required" />
-            </xsd:complexType>
-          </xsd:element>
-        </xsd:choice>
-      </xsd:complexType>
-    </xsd:element>
-  </xsd:schema>
-  <resheader name="resmimetype">
-    <value>text/microsoft-resx</value>
-  </resheader>
-  <resheader name="version">
-    <value>2.0</value>
-  </resheader>
-  <resheader name="reader">
-    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
-  </resheader>
-  <resheader name="writer">
-    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
-  </resheader>
-  <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
-  <data name="GetTokenFromWechat" type="System.Resources.ResXFileRef, System.Windows.Forms">
-    <value>..\Resources\GetTokenFromWechat.dll;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
-  </data>
-</root>

BIN
SheepSheep/Resources/GetTokenFromWechat.dll


+ 3 - 13
SheepSheep/SheepSheep.csproj

@@ -22,6 +22,7 @@
     <DefineConstants>DEBUG;TRACE</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
     <PlatformTarget>AnyCPU</PlatformTarget>
@@ -31,6 +32,7 @@
     <DefineConstants>TRACE</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
   </PropertyGroup>
   <ItemGroup>
     <Reference Include="System" />
@@ -61,22 +63,13 @@
     <Compile Include="InputDialog.cs" />
     <Compile Include="Program.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="WcToken.cs" />
     <EmbeddedResource Include="Form1.resx">
       <DependentUpon>Form1.cs</DependentUpon>
     </EmbeddedResource>
     <EmbeddedResource Include="FrmInputDialog.resx">
       <DependentUpon>FrmInputDialog.cs</DependentUpon>
     </EmbeddedResource>
-    <EmbeddedResource Include="Properties\Resources.resx">
-      <Generator>ResXFileCodeGenerator</Generator>
-      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
-      <SubType>Designer</SubType>
-    </EmbeddedResource>
-    <Compile Include="Properties\Resources.Designer.cs">
-      <AutoGen>True</AutoGen>
-      <DependentUpon>Resources.resx</DependentUpon>
-      <DesignTime>True</DesignTime>
-    </Compile>
     <None Include="Properties\Settings.settings">
       <Generator>SettingsSingleFileGenerator</Generator>
       <LastGenOutput>Settings.Designer.cs</LastGenOutput>
@@ -90,8 +83,5 @@
   <ItemGroup>
     <None Include="App.config" />
   </ItemGroup>
-  <ItemGroup>
-    <Content Include="Resources\GetTokenFromWechat.dll" />
-  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
 </Project>

+ 141 - 0
SheepSheep/WcToken.cs

@@ -0,0 +1,141 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+using System.Text.RegularExpressions;
+
+namespace SheepSheep
+{
+    class WcToken
+    {
+        [DllImport("kernel32.dll")]
+        private static extern uint GetLastError();
+        [DllImport("kernel32.dll")]
+        private static extern int OpenProcess(int dwDesiredAccess, int bInheritHandle, int dwProcessId);
+        [DllImport("Kernel32.dll", SetLastError = true)]
+        private static extern int VirtualQueryEx(IntPtr hProcess, IntPtr lpAddress, out MEMORY_BASIC_INFORMATION lpBuffer, int dwLength);
+        [DllImport("Kernel32.dll")]
+        public static extern bool ReadProcessMemory(IntPtr handle, int address, byte[] data, int size, byte[] read);
+        private struct MEMORY_BASIC_INFORMATION
+        {
+            public int BaseAddress;
+            public int AllocationBase;
+            public int AllocationProtect;
+            public int RegionSize;
+            public int State;
+            public int Protect;
+            public int lType;
+        }
+        const int PROCESS_ALL_ACCESS = 0x1F0FFF;
+        private static byte[] GetBlankBytes(int Length)
+        {
+            byte[] AOB = new byte[Length];
+            for (int i = 0; i < Length; i++)
+            {
+                AOB[i] = 0;
+            }
+            return AOB;
+        }
+        public static int IndexOf(byte[] array, byte[] pattern, int startOffset = 0)
+        {
+            int success = 0;
+            for (int i = startOffset; i < array.Length; i++)
+            {
+                if (array[i] == pattern[success])
+                {
+                    success++;
+                }
+                else
+                {
+                    success = 0;
+                }
+                if (pattern.Length == success)
+                {
+                    return i - pattern.Length + 1;
+                }
+            }
+            return -1;
+        }
+        private static unsafe long IndexOf2(byte[] haystack, byte[] needle, long startOffset = 0)
+        {
+            fixed (byte* h = haystack) fixed (byte* n = needle)
+            {
+                for (byte* hNext = h + startOffset, hEnd = h + haystack.LongLength + 1 - needle.LongLength, nEnd = n + needle.LongLength; hNext < hEnd; hNext++)
+                    for (byte* hInc = hNext, nInc = n; *nInc == *hInc; hInc++)
+                        if (++nInc == nEnd)
+                            return hNext - h;
+                return -1;
+            }
+        }
+        private static string getSubString(string text, string start, string end)
+        {
+            Regex regex = new Regex("(?<=(" + start + "))[.\\s\\S]*?(?=(" + end + "))", RegexOptions.Multiline | RegexOptions.Singleline);
+            return regex.Match(text).Value;
+        }
+        private static string ReadMemoryString(IntPtr HWND, int IpAddr, int length)
+        {
+            byte[] readByte = GetBlankBytes(length);
+            byte[] readBytes = GetBlankBytes(length);
+            ReadProcessMemory(HWND, IpAddr, readByte, length, readBytes);
+            return System.Text.Encoding.UTF8.GetString(readByte);
+        }
+        private static List<int> MemorySearch(IntPtr HWND, byte[] content)
+        {
+            int IpAddr = 0x000000;
+            List<int> foundList = new List<int>();
+            MEMORY_BASIC_INFORMATION mbi = new MEMORY_BASIC_INFORMATION();
+            while (VirtualQueryEx(HWND, (IntPtr)IpAddr, out mbi, 28) != 0)
+            {
+                if (mbi.Protect != 16 && mbi.Protect != 1 && mbi.Protect != 512)
+                {
+                    byte[] readByte = GetBlankBytes(mbi.RegionSize);
+                    byte[] readBytes = GetBlankBytes(mbi.RegionSize);
+                    bool isRead = false;
+                    int position = 0;
+                    isRead = ReadProcessMemory(HWND, IpAddr, readByte, mbi.RegionSize, readBytes);
+                    while (isRead)
+                    {
+                        position = (int)IndexOf(readByte, content, position);
+                        if (position == -1)
+                        {
+                            break;
+                        }
+                        else
+                        {
+                            foundList.Add(IpAddr + position);
+                        }
+                        position = position + content.Length;
+                    }
+                }
+                IpAddr = IpAddr + mbi.RegionSize;
+            }
+            return foundList;
+        }
+
+        public static string GetTokenFromWechat()
+        {
+            Process[] processes = Process.GetProcesses();
+            byte[] searchStr = System.Text.Encoding.UTF8.GetBytes("\",\"token\":\"");
+            foreach (Process process in processes)
+            {
+                if (process.ProcessName.Equals("WeChatAppEx"))
+                {
+                    IntPtr HWND = (IntPtr)OpenProcess(PROCESS_ALL_ACCESS, 0, process.Id);
+                    List<int> foundList = MemorySearch(HWND, searchStr);
+                    foreach (var item in foundList)
+                    {
+                        string ret = ReadMemoryString(HWND, item, 1024);
+                        string token = getSubString(ret, "\",\"token\":\"", "\",\"");
+                        if (!token.Equals("") && token.IndexOf("eyJ") != -1)
+                        {
+                            return token;
+                        }
+                    }
+                }
+            }
+            return "false";
+        }
+    }
+}