First we decompiled the program using dnSpy, yielding:
using System;
using System.CodeDom.Compiler;
using System.ComponentModel;
using System.Diagnostics;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;
namespace FlagCalculatorApp
{
// Token: 0x02000003 RID: 3
public class MainWindow : Window, IComponentConnector
{
// Token: 0x06000004 RID: 4 RVA: 0x0000207E File Offset: 0x0000027E
public MainWindow()
{
this.InitializeComponent();
}
// Token: 0x06000005 RID: 5 RVA: 0x0000208C File Offset: 0x0000028C
private void Calc(ProgressBar progress, TextBox flag, Label info)
{
MainWindow.<>c__DisplayClass1_0 CS$<>8__locals1 = new MainWindow.<>c__DisplayClass1_0();
CS$<>8__locals1.progress = progress;
CS$<>8__locals1.flag = flag;
CS$<>8__locals1.info = info;
CS$<>8__locals1.<>4__this = this;
CS$<>8__locals1.val = 0u;
uint i;
uint j;
for (i = 0u; i < 12852275u; i = j + 1u)
{
if (i % 1000u == 0u)
{
base.Dispatcher.Invoke(delegate()
{
CS$<>8__locals1.progress.Value = 1u + i * 99u / 12852275u;
});
}
CS$<>8__locals1.val = this.Calc5(this.Calc3(this.Calc6(i, 13u), CS$<>8__locals1.val), i);
j = i;
}
base.Dispatcher.Invoke(delegate()
{
CS$<>8__locals1.progress.Value = 100.0;
CS$<>8__locals1.flag.Text = "pactf{dot" + CS$<>8__locals1.val + "N3T}";
CS$<>8__locals1.info.Content = "flag calculated!";
CS$<>8__locals1.<>4__this.button.IsEnabled = true;
});
}
// Token: 0x06000006 RID: 6 RVA: 0x00002168 File Offset: 0x00000368
private void Button_Click(object sender, RoutedEventArgs e)
{
this.button.IsEnabled = false;
this.flag.Text = "";
this.info.Content = "calculating flag...";
this.progress.Value = 1.0;
new Thread(delegate()
{
this.Calc(this.progress, this.flag, this.info);
}).Start();
}
// Token: 0x06000007 RID: 7 RVA: 0x000021CB File Offset: 0x000003CB
private uint Calc1(uint a)
{
return a + 1337u - 1336u;
}
// Token: 0x06000008 RID: 8 RVA: 0x000021DA File Offset: 0x000003DA
private uint Calc2(uint a)
{
return a * 9u - (8u * a + 200u) + 199u;
}
// Token: 0x06000009 RID: 9 RVA: 0x000021F0 File Offset: 0x000003F0
private uint Calc3(uint a, uint b)
{
uint num = 0u;
for (uint num2 = 0u; num2 < a; num2 += 1u)
{
num = this.Calc1(num);
}
for (uint num3 = 0u; num3 < b; num3 += 1u)
{
num = this.Calc1(num);
}
return num;
}
// Token: 0x0600000A RID: 10 RVA: 0x00002228 File Offset: 0x00000428
private uint Calc4(uint a, uint b)
{
uint num = this.Calc3(a, 0u);
int num2 = 0;
while ((long)num2 < (long)((ulong)b))
{
num = this.Calc2(num);
num2++;
}
return num;
}
// Token: 0x0600000B RID: 11 RVA: 0x00002258 File Offset: 0x00000458
private uint Calc5(uint a, uint b)
{
uint num = 0u;
int num2 = 0;
while ((long)num2 < (long)((ulong)b))
{
num = this.Calc3(num, a);
num2++;
}
return num;
}
// Token: 0x0600000C RID: 12 RVA: 0x00002280 File Offset: 0x00000480
private uint Calc6(uint a, uint b)
{
uint num = a;
int num2 = 0;
while (num >= b)
{
num = this.Calc4(num, b);
num2++;
}
return num;
}
// Token: 0x0600000D RID: 13 RVA: 0x000022A8 File Offset: 0x000004A8
[DebuggerNonUserCode]
[GeneratedCode("PresentationBuildTasks", "4.0.0.0")]
public void InitializeComponent()
{
if (this._contentLoaded)
{
return;
}
this._contentLoaded = true;
Uri resourceLocator = new Uri("/FlagCalculatorApp;component/mainwindow.xaml", UriKind.Relative);
Application.LoadComponent(this, resourceLocator);
}
// Token: 0x0600000E RID: 14 RVA: 0x000022D8 File Offset: 0x000004D8
[DebuggerNonUserCode]
[GeneratedCode("PresentationBuildTasks", "4.0.0.0")]
[EditorBrowsable(EditorBrowsableState.Never)]
void IComponentConnector.Connect(int connectionId, object target)
{
switch (connectionId)
{
case 1:
this.flag = (TextBox)target;
return;
case 2:
this.label = (Label)target;
return;
case 3:
this.button = (Button)target;
this.button.Click += this.Button_Click;
return;
case 4:
this.progress = (ProgressBar)target;
return;
case 5:
this.info = (Label)target;
return;
case 6:
this.image = (Image)target;
return;
default:
this._contentLoaded = true;
return;
}
}
// Token: 0x04000001 RID: 1
internal TextBox flag;
// Token: 0x04000002 RID: 2
internal Label label;
// Token: 0x04000003 RID: 3
internal Button button;
// Token: 0x04000004 RID: 4
internal ProgressBar progress;
// Token: 0x04000005 RID: 5
internal Label info;
// Token: 0x04000006 RID: 6
internal Image image;
// Token: 0x04000007 RID: 7
private bool _contentLoaded;
}
}
I made a guess that not much was being done, and that the program was only slow due to c# being slow. And rewrote it into C.
#include <stdio.h>
#include <stdlib.h>
unsigned int calc1(unsigned int num) {
return num + 1337u - 1336u;
}
unsigned calc2(unsigned a) {
return a * 9u - (8u * a + 200u) + 199u;
}
unsigned calc3(unsigned int a, unsigned int b) {
unsigned int num = 0;
for (unsigned int num2 = 0; num2 < a; num2++) {
num = calc1(num);
}
for (unsigned int num3 = 0; num3 < b; num3++) {
num = calc1(num);
}
return num;
}
unsigned int calc4(unsigned int a, unsigned int b) {
unsigned int num = calc3(a, 0);
int num2 = 0;
while ((long)num2 < (long)((unsigned long)b)) {
num = calc2(num);
num2++;
}
return num;
}
unsigned int calc5(unsigned int a, unsigned int b) {
unsigned int num = 0;
int num2 = 0;
while ((long)num2 < (long)((unsigned long)b)) {
num = calc3(num, a);
num2++;
}
return num;
}
unsigned int calc6(unsigned int a, unsigned int b) {
unsigned int num = a;
int num2 = 0;
while (num >= b) {
num = calc4(num, b);
num2++;
}
return num;
}
int main() {
unsigned int val = 0;
unsigned int i, j;
for (i = 0; i < 12852275; i = j + 1) {
val = calc5(calc3(calc6(i, 13), val), i);
j = i;
}
printf("pactf{dot%uN3T}\n", val);
}
The result is: pactf{dot4019346342N3T}