diff --git a/Catswords.DataType.Client/App.config b/Catswords.DataType.Client/App.config
new file mode 100644
index 0000000..193aecc
--- /dev/null
+++ b/Catswords.DataType.Client/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Catswords.DataType.Client/Catswords.DataType.Client.csproj b/Catswords.DataType.Client/Catswords.DataType.Client.csproj
new file mode 100644
index 0000000..e7a09ce
--- /dev/null
+++ b/Catswords.DataType.Client/Catswords.DataType.Client.csproj
@@ -0,0 +1,105 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {72A9E640-F785-4202-9CEA-BEC46A9B09B8}
+ WinExe
+ Catswords.DataType.Client
+ Catswords.DataType.Client
+ v4.8
+ 512
+ true
+ true
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Form
+
+
+ Form1.cs
+
+
+
+
+
+
+
+
+
+ UserControl
+
+
+ UserControl1.cs
+
+
+ Form1.cs
+
+
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+ Designer
+
+
+ True
+ Resources.resx
+ True
+
+
+ UserControl1.cs
+
+
+
+ SettingsSingleFileGenerator
+ Settings.Designer.cs
+
+
+ True
+ Settings.settings
+ True
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Catswords.DataType.Client/Form1.Designer.cs b/Catswords.DataType.Client/Form1.Designer.cs
new file mode 100644
index 0000000..5c9c6e1
--- /dev/null
+++ b/Catswords.DataType.Client/Form1.Designer.cs
@@ -0,0 +1,50 @@
+namespace Catswords.DataType.Client
+{
+ partial class Form1
+ {
+ ///
+ /// 필수 디자이너 변수입니다.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// 사용 중인 모든 리소스를 정리합니다.
+ ///
+ /// 관리되는 리소스를 삭제해야 하면 true이고, 그렇지 않으면 false입니다.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form 디자이너에서 생성한 코드
+
+ ///
+ /// 디자이너 지원에 필요한 메서드입니다.
+ /// 이 메서드의 내용을 코드 편집기로 수정하지 마세요.
+ ///
+ private void InitializeComponent()
+ {
+ this.SuspendLayout();
+ //
+ // Form1
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.BackColor = System.Drawing.SystemColors.Window;
+ this.ClientSize = new System.Drawing.Size(384, 469);
+ this.MaximizeBox = false;
+ this.MinimizeBox = false;
+ this.Name = "Form1";
+ this.Text = "Catswords.DataType.Client";
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+ }
+}
+
diff --git a/Catswords.DataType.Client/Form1.cs b/Catswords.DataType.Client/Form1.cs
new file mode 100644
index 0000000..08f9d9f
--- /dev/null
+++ b/Catswords.DataType.Client/Form1.cs
@@ -0,0 +1,15 @@
+using System.Windows.Forms;
+
+namespace Catswords.DataType.Client
+{
+ public partial class Form1 : Form
+ {
+ public Form1()
+ {
+ InitializeComponent();
+
+ UserControl1 userControl1 = new UserControl1(this);
+ this.Controls.Add(userControl1);
+ }
+ }
+}
diff --git a/Catswords.DataType.Client/Form1.resx b/Catswords.DataType.Client/Form1.resx
new file mode 100644
index 0000000..1af7de1
--- /dev/null
+++ b/Catswords.DataType.Client/Form1.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/Catswords.DataType.Client/Helper/FileCompany.cs b/Catswords.DataType.Client/Helper/FileCompany.cs
new file mode 100644
index 0000000..08737a3
--- /dev/null
+++ b/Catswords.DataType.Client/Helper/FileCompany.cs
@@ -0,0 +1,101 @@
+using System;
+using System.Diagnostics;
+using System.Reflection;
+using System.Security.Cryptography.X509Certificates;
+
+namespace Catswords.DataType.Client.Helper
+{
+ public static class FileCompany
+ {
+ static public string Read(string filePath)
+ {
+ // 회사 정보 추출
+ string[] companies = new string[] {
+ GetCompanyInfo(filePath),
+ GetProductName(filePath),
+ GetCopyrightInfo(filePath),
+ GetOrganization(filePath)
+ };
+ foreach (string company in companies)
+ {
+ if (company != null && !company.Equals(string.Empty))
+ {
+ return company;
+ }
+ }
+
+ return "Unknown";
+ }
+
+ public static string GetOrganization(string filePath)
+ {
+ string organization = string.Empty;
+
+ // 서명된 파일인 경우 인증서 정보 추출
+ X509Certificate2 certificate = GetCertificateInfo(filePath);
+ if (certificate != null)
+ {
+ // Subject 필드에서 O (Organization) 값을 찾아 회사 정보 추출
+ string[] fields = certificate.Subject.Split(',');
+
+ foreach (string field in fields)
+ {
+ string[] keyValue = field.Trim().Split('=');
+
+ if (keyValue.Length == 2 && keyValue[0].Trim().Equals("O", StringComparison.OrdinalIgnoreCase))
+ {
+ organization = keyValue[1].Trim();
+ }
+ }
+ }
+
+ return organization;
+ }
+
+ public static string GetCompanyInfo(string filePath)
+ {
+ FileVersionInfo versionInfo = FileVersionInfo.GetVersionInfo(filePath);
+ return versionInfo.CompanyName;
+ }
+
+ public static string GetProductName(string filePath)
+ {
+ FileVersionInfo versionInfo = FileVersionInfo.GetVersionInfo(filePath);
+ return versionInfo.ProductName;
+ }
+
+ public static string GetCopyrightInfo(string filePath)
+ {
+ FileVersionInfo versionInfo = FileVersionInfo.GetVersionInfo(filePath);
+ return versionInfo.LegalCopyright;
+ }
+
+ static X509Certificate2 GetCertificateInfo(string filePath)
+ {
+ // GetCertificateInfo 구현
+ try
+ {
+ // 파일에 디지털 서명이 있는지 확인
+ Assembly assembly = Assembly.LoadFile(filePath);
+ X509Certificate2 certificate = new X509Certificate2(assembly.Location);
+
+ // 서명이 유효한지 확인 (옵션)
+ X509Chain chain = new X509Chain();
+ chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; // 여러 인증서를 사용하는 경우 인증서 연쇄를 무시할 수 있습니다.
+
+ if (chain.Build(certificate))
+ {
+ return certificate;
+ }
+ else
+ {
+ return null;
+ }
+ }
+ catch
+ {
+ return null;
+ }
+ }
+ }
+}
diff --git a/Catswords.DataType.Client/Helper/FileMagic.cs b/Catswords.DataType.Client/Helper/FileMagic.cs
new file mode 100644
index 0000000..1f10863
--- /dev/null
+++ b/Catswords.DataType.Client/Helper/FileMagic.cs
@@ -0,0 +1,36 @@
+using System;
+using System.IO;
+
+namespace Catswords.DataType.Client.Helper
+{
+ public static class FileMagic
+ {
+ public static string Error = string.Empty;
+
+ public static string Read(string filePath)
+ {
+ string hexString = "";
+
+ try
+ {
+ // 파일 열기
+ using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
+ {
+ // 첫 3 바이트 읽기
+ byte[] buffer = new byte[3] { 0x00, 0x00, 0x00 };
+ int bytesRead = fs.Read(buffer, 0, 3);
+
+ // 16진수로 변환하여 출력
+ hexString = BitConverter.ToString(buffer).Replace("-", string.Empty).ToLower();
+ }
+ }
+ catch (Exception ex)
+ {
+ hexString = "000000";
+ Error = ex.Message;
+ }
+
+ return hexString;
+ }
+ }
+}
diff --git a/Catswords.DataType.Client/Helper/ImpHash.cs b/Catswords.DataType.Client/Helper/ImpHash.cs
new file mode 100644
index 0000000..b808aa5
--- /dev/null
+++ b/Catswords.DataType.Client/Helper/ImpHash.cs
@@ -0,0 +1,68 @@
+using System;
+using System.IO;
+using System.Security.Cryptography;
+using System.Text;
+
+namespace Catswords.DataType.Client.Helper
+{
+ public static class ImpHash
+ {
+ public static string Calculate(string filePath)
+ {
+ string imphash = "";
+
+ using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
+ {
+ using (BinaryReader binaryReader = new BinaryReader(fileStream))
+ {
+ // DOS Header 크기만큼 스킵
+ binaryReader.BaseStream.Seek(0x3C, SeekOrigin.Begin);
+ int peHeaderOffset = binaryReader.ReadInt32();
+
+ // PE Header로 이동
+ binaryReader.BaseStream.Seek(peHeaderOffset, SeekOrigin.Begin);
+
+ // Signature 확인
+ uint signature = binaryReader.ReadUInt32();
+ if (signature != 0x00004550) // "PE\0\0"
+ {
+ throw new InvalidOperationException("Invalid PE file");
+ }
+
+ // Optional Header에서 Import Table Offset 찾기
+ binaryReader.BaseStream.Seek(20, SeekOrigin.Current); // COFF 파일 헤더 크기만큼 스킵
+ ushort optionalHeaderSize = binaryReader.ReadUInt16();
+ binaryReader.BaseStream.Seek(42, SeekOrigin.Current); // ImageBase 크기만큼 스킵
+
+ int importTableOffset = peHeaderOffset + 24 + optionalHeaderSize;
+ binaryReader.BaseStream.Seek(importTableOffset, SeekOrigin.Begin);
+
+ // Import Table에서 imphash 생성
+ StringBuilder imphashBuilder = new StringBuilder();
+ while (true)
+ {
+ uint lookupTableRVA = binaryReader.ReadUInt32();
+ if (lookupTableRVA == 0)
+ {
+ break;
+ }
+
+ binaryReader.BaseStream.Seek(12, SeekOrigin.Current); // 다른 필드들을 스킵
+ binaryReader.BaseStream.Seek(4, SeekOrigin.Current); // 항상 0인 TimeDateStamp 필드를 스킵
+
+ imphashBuilder.Append(lookupTableRVA.ToString("X8"));
+ }
+
+ // MD5 해시 생성
+ using (MD5 md5 = MD5.Create())
+ {
+ byte[] hashBytes = md5.ComputeHash(Encoding.ASCII.GetBytes(imphashBuilder.ToString()));
+ imphash = BitConverter.ToString(hashBytes).Replace("-", string.Empty).ToLower();
+ }
+ }
+ }
+
+ return imphash;
+ }
+ }
+}
diff --git a/Catswords.DataType.Client/Helper/Timeline.cs b/Catswords.DataType.Client/Helper/Timeline.cs
new file mode 100644
index 0000000..ecf99f0
--- /dev/null
+++ b/Catswords.DataType.Client/Helper/Timeline.cs
@@ -0,0 +1,90 @@
+using Newtonsoft.Json.Linq;
+using Catswords.DataType.Client.Model;
+using System;
+using System.Collections.Generic;
+using System.Net.Http;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+
+namespace Catswords.DataType.Client.Helper
+{
+ public class Timeline
+ {
+ public string ApiBaseUrl;
+ public string AccessToken;
+ public List Indicators;
+ public string ResponseText;
+
+ public Timeline(string host, string access_token)
+ {
+ ApiBaseUrl = $"https://{host}/api/v1/timelines/tag";
+ AccessToken = access_token;
+ Indicators = new List();
+ }
+
+ public static string RemoveHtmlTags(string input)
+ {
+ // 정규 표현식을 사용하여 HTML 태그 제거
+ string pattern = "<.*?>";
+ string replacement = "";
+ Regex regex = new Regex(pattern);
+ string result = regex.Replace(input, replacement);
+
+ return result;
+ }
+
+ public static string FormatDateTime(string dateString)
+ {
+ string formattedDateTime = "";
+
+ // 날짜와 시간을 파싱
+ if (DateTime.TryParseExact(dateString, "MM/dd/yyyy HH:mm:ss", null, System.Globalization.DateTimeStyles.None, out DateTime parsedDateTime))
+ {
+ // UTC에서 로컬 시간으로 변환
+ DateTime localTime = parsedDateTime.ToLocalTime();
+
+ // 현재 스레드의 문화권에 따라 날짜와 시간 출력
+ formattedDateTime = localTime.ToString();
+ }
+
+ return formattedDateTime;
+ }
+
+ public void Fetch(string q)
+ {
+ using (HttpClient client = new HttpClient())
+ {
+ client.DefaultRequestHeaders.Add("Authorization", $"Bearer {AccessToken}");
+
+ try
+ {
+ // 데이터 요청
+ Task responseTask = client.GetAsync($"{ApiBaseUrl}/{q}");
+ responseTask.Wait();
+
+ // 응답 본문 저장
+ HttpResponseMessage response = responseTask.Result;
+ Task readAsStringTask = response.Content.ReadAsStringAsync();
+ readAsStringTask.Wait();
+ ResponseText = readAsStringTask.Result;
+
+ // JSON 파싱
+ JArray statuses = JArray.Parse(ResponseText);
+
+ foreach (var status in statuses)
+ {
+ string createdAt = status["created_at"].Value();
+ string content = status["content"].Value();
+
+ Indicators.Add(new Indicator
+ {
+ CreatedAt = FormatDateTime(createdAt),
+ Content = RemoveHtmlTags(content)
+ });
+ }
+ }
+ catch { }
+ }
+ }
+ }
+}
diff --git a/Catswords.DataType.Client/Model/Indicator.cs b/Catswords.DataType.Client/Model/Indicator.cs
new file mode 100644
index 0000000..a47f0ee
--- /dev/null
+++ b/Catswords.DataType.Client/Model/Indicator.cs
@@ -0,0 +1,10 @@
+namespace Catswords.DataType.Client.Model
+{
+ public class Indicator
+ {
+ public string Id { get; set; }
+ public string Content { get; set; }
+ public string Url { get; set; }
+ public string CreatedAt { get; set; }
+ }
+}
diff --git a/Catswords.DataType.Client/Program.cs b/Catswords.DataType.Client/Program.cs
new file mode 100644
index 0000000..bcc3e93
--- /dev/null
+++ b/Catswords.DataType.Client/Program.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace Catswords.DataType.Client
+{
+ internal static class Program
+ {
+ ///
+ /// 해당 애플리케이션의 주 진입점입니다.
+ ///
+ [STAThread]
+ static void Main()
+ {
+ Application.EnableVisualStyles();
+ Application.SetCompatibleTextRenderingDefault(false);
+ Application.Run(new Form1());
+ }
+ }
+}
diff --git a/Catswords.DataType.Client/Properties/AssemblyInfo.cs b/Catswords.DataType.Client/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..4f50ff7
--- /dev/null
+++ b/Catswords.DataType.Client/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// 어셈블리에 대한 일반 정보는 다음 특성 집합을 통해
+// 제어됩니다. 어셈블리와 관련된 정보를 수정하려면
+// 이러한 특성 값을 변경하세요.
+[assembly: AssemblyTitle("Catswords.DataType.Client")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Catswords.DataType.Client")]
+[assembly: AssemblyCopyright("Copyright © 2024")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// ComVisible을 false로 설정하면 이 어셈블리의 형식이 COM 구성 요소에
+// 표시되지 않습니다. COM에서 이 어셈블리의 형식에 액세스하려면
+// 해당 형식에 대해 ComVisible 특성을 true로 설정하세요.
+[assembly: ComVisible(false)]
+
+// 이 프로젝트가 COM에 노출되는 경우 다음 GUID는 typelib의 ID를 나타냅니다.
+[assembly: Guid("72a9e640-f785-4202-9cea-bec46a9b09b8")]
+
+// 어셈블리의 버전 정보는 다음 네 가지 값으로 구성됩니다.
+//
+// 주 버전
+// 부 버전
+// 빌드 번호
+// 수정 버전
+//
+// 모든 값을 지정하거나 아래와 같이 '*'를 사용하여 빌드 번호 및 수정 번호를
+// 기본값으로 할 수 있습니다.
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Catswords.DataType.Client/Properties/Resources.Designer.cs b/Catswords.DataType.Client/Properties/Resources.Designer.cs
new file mode 100644
index 0000000..5dfeee8
--- /dev/null
+++ b/Catswords.DataType.Client/Properties/Resources.Designer.cs
@@ -0,0 +1,73 @@
+//------------------------------------------------------------------------------
+//
+// 이 코드는 도구를 사용하여 생성되었습니다.
+// 런타임 버전:4.0.30319.42000
+//
+// 파일 내용을 변경하면 잘못된 동작이 발생할 수 있으며, 코드를 다시 생성하면
+// 이러한 변경 내용이 손실됩니다.
+//
+//------------------------------------------------------------------------------
+
+namespace Catswords.DataType.Client.Properties {
+ using System;
+
+
+ ///
+ /// 지역화된 문자열 등을 찾기 위한 강력한 형식의 리소스 클래스입니다.
+ ///
+ // 이 클래스는 ResGen 또는 Visual Studio와 같은 도구를 통해 StronglyTypedResourceBuilder
+ // 클래스에서 자동으로 생성되었습니다.
+ // 멤버를 추가하거나 제거하려면 .ResX 파일을 편집한 다음 /str 옵션을 사용하여 ResGen을
+ // 다시 실행하거나 VS 프로젝트를 다시 빌드하십시오.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.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() {
+ }
+
+ ///
+ /// 이 클래스에서 사용하는 캐시된 ResourceManager 인스턴스를 반환합니다.
+ ///
+ [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("Catswords.DataType.Client.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// 이 강력한 형식의 리소스 클래스를 사용하여 모든 리소스 조회에 대해 현재 스레드의 CurrentUICulture 속성을
+ /// 재정의합니다.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+
+ ///
+ /// System.Drawing.Bitmap 형식의 지역화된 리소스를 찾습니다.
+ ///
+ internal static System.Drawing.Bitmap image1 {
+ get {
+ object obj = ResourceManager.GetObject("image1", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+ }
+}
diff --git a/Catswords.DataType.Client/Properties/Resources.resx b/Catswords.DataType.Client/Properties/Resources.resx
new file mode 100644
index 0000000..dece6fe
--- /dev/null
+++ b/Catswords.DataType.Client/Properties/Resources.resx
@@ -0,0 +1,124 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+
+ ..\Resources\image1.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
\ No newline at end of file
diff --git a/Catswords.DataType.Client/Properties/Settings.Designer.cs b/Catswords.DataType.Client/Properties/Settings.Designer.cs
new file mode 100644
index 0000000..019b97e
--- /dev/null
+++ b/Catswords.DataType.Client/Properties/Settings.Designer.cs
@@ -0,0 +1,30 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace Catswords.DataType.Client.Properties
+{
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
+ {
+
+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default
+ {
+ get
+ {
+ return defaultInstance;
+ }
+ }
+ }
+}
diff --git a/Catswords.DataType.Client/Properties/Settings.settings b/Catswords.DataType.Client/Properties/Settings.settings
new file mode 100644
index 0000000..3964565
--- /dev/null
+++ b/Catswords.DataType.Client/Properties/Settings.settings
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/Catswords.DataType.Client/Resources/image1.png b/Catswords.DataType.Client/Resources/image1.png
new file mode 100644
index 0000000..b22297f
Binary files /dev/null and b/Catswords.DataType.Client/Resources/image1.png differ
diff --git a/Catswords.DataType.Client/UserControl1.Designer.cs b/Catswords.DataType.Client/UserControl1.Designer.cs
new file mode 100644
index 0000000..64cdf3a
--- /dev/null
+++ b/Catswords.DataType.Client/UserControl1.Designer.cs
@@ -0,0 +1,133 @@
+namespace Catswords.DataType.Client
+{
+ partial class UserControl1
+ {
+ ///
+ /// 필수 디자이너 변수입니다.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// 사용 중인 모든 리소스를 정리합니다.
+ ///
+ /// 관리되는 리소스를 삭제해야 하면 true이고, 그렇지 않으면 false입니다.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region 구성 요소 디자이너에서 생성한 코드
+
+ ///
+ /// 디자이너 지원에 필요한 메서드입니다.
+ /// 이 메서드의 내용을 코드 편집기로 수정하지 마세요.
+ ///
+ private void InitializeComponent()
+ {
+ this.listView1 = new System.Windows.Forms.ListView();
+ this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
+ this.columnHeader2 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
+ this.label1 = new System.Windows.Forms.Label();
+ this.textBox1 = new System.Windows.Forms.TextBox();
+ this.label2 = new System.Windows.Forms.Label();
+ this.linkLabel1 = new System.Windows.Forms.LinkLabel();
+ this.SuspendLayout();
+ //
+ // listView1
+ //
+ this.listView1.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
+ this.columnHeader1,
+ this.columnHeader2});
+ this.listView1.HideSelection = false;
+ this.listView1.Location = new System.Drawing.Point(18, 125);
+ this.listView1.Name = "listView1";
+ this.listView1.Size = new System.Drawing.Size(347, 277);
+ this.listView1.TabIndex = 8;
+ this.listView1.UseCompatibleStateImageBehavior = false;
+ this.listView1.View = System.Windows.Forms.View.Details;
+ //
+ // columnHeader1
+ //
+ this.columnHeader1.Text = "CreatedAt";
+ this.columnHeader1.Width = 120;
+ //
+ // columnHeader2
+ //
+ this.columnHeader2.Text = "Opinion";
+ this.columnHeader2.Width = 200;
+ //
+ // label1
+ //
+ this.label1.AutoSize = true;
+ this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 27.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.label1.Location = new System.Drawing.Point(128, 62);
+ this.label1.Name = "label1";
+ this.label1.Size = new System.Drawing.Size(118, 42);
+ this.label1.TabIndex = 7;
+ this.label1.Text = "label1";
+ //
+ // textBox1
+ //
+ this.textBox1.BackColor = System.Drawing.Color.White;
+ this.textBox1.BorderStyle = System.Windows.Forms.BorderStyle.None;
+ this.textBox1.Location = new System.Drawing.Point(16, 445);
+ this.textBox1.Name = "textBox1";
+ this.textBox1.ReadOnly = true;
+ this.textBox1.Size = new System.Drawing.Size(349, 13);
+ this.textBox1.TabIndex = 11;
+ //
+ // label2
+ //
+ this.label2.AutoSize = true;
+ this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.label2.Location = new System.Drawing.Point(132, 45);
+ this.label2.Name = "label2";
+ this.label2.Size = new System.Drawing.Size(118, 16);
+ this.label2.TabIndex = 10;
+ this.label2.Text = "Conversations with";
+ //
+ // linkLabel1
+ //
+ this.linkLabel1.AutoSize = true;
+ this.linkLabel1.Location = new System.Drawing.Point(15, 416);
+ this.linkLabel1.Name = "linkLabel1";
+ this.linkLabel1.Size = new System.Drawing.Size(122, 13);
+ this.linkLabel1.TabIndex = 9;
+ this.linkLabel1.TabStop = true;
+ this.linkLabel1.Text = "Write a review to this file";
+ this.linkLabel1.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel1_LinkClicked);
+ //
+ // UserControl1
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.BackColor = System.Drawing.SystemColors.Window;
+ this.BackgroundImage = global::Catswords.DataType.Client.Properties.Resources.image1;
+ this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None;
+ this.Controls.Add(this.listView1);
+ this.Controls.Add(this.label1);
+ this.Controls.Add(this.textBox1);
+ this.Controls.Add(this.label2);
+ this.Controls.Add(this.linkLabel1);
+ this.Name = "UserControl1";
+ this.Size = new System.Drawing.Size(433, 457);
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.ListView listView1;
+ private System.Windows.Forms.ColumnHeader columnHeader1;
+ private System.Windows.Forms.ColumnHeader columnHeader2;
+ private System.Windows.Forms.Label label1;
+ private System.Windows.Forms.TextBox textBox1;
+ private System.Windows.Forms.Label label2;
+ private System.Windows.Forms.LinkLabel linkLabel1;
+ }
+}
diff --git a/Catswords.DataType.Client/UserControl1.cs b/Catswords.DataType.Client/UserControl1.cs
new file mode 100644
index 0000000..3ba909d
--- /dev/null
+++ b/Catswords.DataType.Client/UserControl1.cs
@@ -0,0 +1,133 @@
+using Catswords.DataType.Client.Model;
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Windows.Forms;
+
+namespace Catswords.DataType.Client
+{
+ public partial class UserControl1 : UserControl
+ {
+ private string filePath;
+ private string fileMagic;
+ private string fileName;
+ private string fileExtension;
+
+ public UserControl1(Form parent)
+ {
+ InitializeComponent();
+
+ // Store the file path.
+ filePath = OpenFileDialog();
+ if (string.IsNullOrEmpty(filePath))
+ {
+ MessageBox.Show("Failed to get a file name", "Catswords.DataType.Client");
+ parent.Close();
+ return;
+ }
+
+ // Get first 4 bytes from the file.
+ fileMagic = Helper.FileMagic.Read(filePath);
+
+ // Show file magic to the label
+ label1.Text = "#0x" + fileMagic;
+ if (Helper.FileMagic.Error != string.Empty)
+ {
+ textBox1.Text = Helper.FileMagic.Error;
+ }
+
+ // Get file name and file extension
+ try
+ {
+ fileExtension = Path.GetExtension(filePath);
+ fileName = Path.GetFileName(filePath);
+ if (fileExtension.Length > 0 && fileExtension.Substring(0, 1) == ".")
+ {
+ fileExtension = fileExtension.Substring(1);
+ }
+ }
+ catch
+ {
+ fileExtension = "";
+ fileName = "";
+ }
+
+ // Request a timeline
+ var search = new Helper.Timeline("catswords.social", "HDVTEfLswvSJZq5MRpim2tp7DifTcgKbMl0mBM5-uHw");
+
+ // fetch data by file magic
+ search.Fetch("0x" + fileMagic);
+
+ // if PE format (ImpHash)
+ if (fileMagic.StartsWith("4d5a"))
+ {
+ try
+ {
+ string imphash = Helper.ImpHash.Calculate(filePath);
+ search.Fetch(imphash);
+
+ string companyInfo = Helper.FileCompany.Read(filePath);
+ search.Fetch(companyInfo);
+
+ textBox1.Text = "ImpHash=" + imphash + "; CompanyInfo=" + companyInfo;
+ }
+ catch (Exception ex)
+ {
+ textBox1.Text = ex.Message;
+ }
+ }
+
+ // fetch data by file extension
+ if (fileExtension.Length > 0)
+ {
+ search.Fetch(fileExtension);
+
+ // if Office365 format
+ if (fileExtension.StartsWith("xls") || fileExtension.StartsWith("ppt") || fileExtension.StartsWith("doc"))
+ {
+ search.Fetch("office365");
+ }
+ }
+
+ // if it contains ransomware keywords
+ if (fileName.ToLower().Contains("readme") || fileName.ToLower().Contains("decrypt"))
+ {
+ search.Fetch("ransomware");
+ }
+
+ // if IoC (Indicators of Compomise) mode
+ if (fileMagic == "58354f") // EICAR test file header
+ {
+ search.Fetch("ioc");
+ }
+
+ // Show the timeline
+ foreach (Indicator ind in search.Indicators)
+ {
+ listView1.Items.Add(new ListViewItem(new string[] { ind.CreatedAt, ind.Content }));
+ }
+ }
+
+ public string OpenFileDialog()
+ {
+ string filePath = null;
+
+ using (OpenFileDialog openFileDialog = new OpenFileDialog())
+ {
+ if (openFileDialog.ShowDialog() == DialogResult.OK)
+ {
+ //Get the path of specified file
+ filePath = openFileDialog.FileName;
+ }
+ }
+
+ return filePath;
+ }
+
+ private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
+ {
+ Process.Start("https://catswords.social/auth/sign_up");
+ }
+ }
+}
diff --git a/Catswords.DataType.Client/UserControl1.resx b/Catswords.DataType.Client/UserControl1.resx
new file mode 100644
index 0000000..1af7de1
--- /dev/null
+++ b/Catswords.DataType.Client/UserControl1.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/Catswords.DataType.Client/packages.config b/Catswords.DataType.Client/packages.config
new file mode 100644
index 0000000..0b14af3
--- /dev/null
+++ b/Catswords.DataType.Client/packages.config
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/SocialOnTheFile.sln b/SocialOnTheFile.sln
index 69071a1..8d82765 100644
--- a/SocialOnTheFile.sln
+++ b/SocialOnTheFile.sln
@@ -5,6 +5,8 @@ VisualStudioVersion = 17.8.34322.80
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SocialOnTheFile", "SocialOnTheFile\SocialOnTheFile.csproj", "{35CC3E28-05C8-478B-B5A2-15FCE468CE34}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Catswords.DataType.Client", "Catswords.DataType.Client\Catswords.DataType.Client.csproj", "{72A9E640-F785-4202-9CEA-BEC46A9B09B8}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -27,6 +29,18 @@ Global
{35CC3E28-05C8-478B-B5A2-15FCE468CE34}.Release|x64.Build.0 = Release|x64
{35CC3E28-05C8-478B-B5A2-15FCE468CE34}.Release|x86.ActiveCfg = Release|x86
{35CC3E28-05C8-478B-B5A2-15FCE468CE34}.Release|x86.Build.0 = Release|x86
+ {72A9E640-F785-4202-9CEA-BEC46A9B09B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {72A9E640-F785-4202-9CEA-BEC46A9B09B8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {72A9E640-F785-4202-9CEA-BEC46A9B09B8}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {72A9E640-F785-4202-9CEA-BEC46A9B09B8}.Debug|x64.Build.0 = Debug|Any CPU
+ {72A9E640-F785-4202-9CEA-BEC46A9B09B8}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {72A9E640-F785-4202-9CEA-BEC46A9B09B8}.Debug|x86.Build.0 = Debug|Any CPU
+ {72A9E640-F785-4202-9CEA-BEC46A9B09B8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {72A9E640-F785-4202-9CEA-BEC46A9B09B8}.Release|Any CPU.Build.0 = Release|Any CPU
+ {72A9E640-F785-4202-9CEA-BEC46A9B09B8}.Release|x64.ActiveCfg = Release|Any CPU
+ {72A9E640-F785-4202-9CEA-BEC46A9B09B8}.Release|x64.Build.0 = Release|Any CPU
+ {72A9E640-F785-4202-9CEA-BEC46A9B09B8}.Release|x86.ActiveCfg = Release|Any CPU
+ {72A9E640-F785-4202-9CEA-BEC46A9B09B8}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE