2023
-
Classifying More With Less: New VGL4NT Update
TLDR:
- Packed malware machine learning classifier can only previously identify 10 packers
- Solution was a customized version of model ensembling, which is to train multiple models and resolve their results
- It works with a slight caveat of more extended training and processing, which I could happily live with
I recently presented VGL4NT, my tool that uses machine learning to classify packed malware, at the Blackhat Middle East and Africa meetup. During my talk, I candidly shared one of the tool's limitations which is it can only identify 10 packers because of my hardware constraints. If I want it to be able to identify more, I need to get more GPU (which will be costly) or keep my money and come up with a clever solution. Well, this post is about the latter.
A Simple Solution
The solution I came up with isn't exactly original. It's based on Task Decomposition, which …
-
Classifying Malware Packers Using Machine Learning
The recent rise in popularity of AI reignited my interest in machine learning. It inspired me to dive deeper into understanding how it can be applied to malware analysis and, more importantly, how to better detect malware packers, as almost every malware nowadays uses them.
My research and experiments eventually led me to make a web app, which I call the VGL4NT Malware Packer Classifier (https://packers.vgl4nt.com/).).
(For those curious, V.G.L.4.N.T. is a play on "Vigilant" and stands for "Visual Guided Learning 4 Neutralizing Threats")
Current State of Packer Detection
Traditional packer detection approaches like DiE (Detect it Easy) and Yara rules depend on known signatures and patterns to identify packers. These tools scrutinize a file for specific indicators, like unique sequences of bytes or strings. While effective in many cases, they have drawbacks, like when a packer is modified or if the …
-
Adding Automation to Blue-Jupyter Malware Notebook
I came across the Blue-Jupyter project on Github while researching Jupyter notebooks. This short demo video got me excited, so I cloned the project and added some improvements that automate many things when I am looking for malware to investigate.
What are Jupyter Notebooks?
For readers who may be unfamiliar, Jupyter Notebooks are a web-based tool that allows users to create and share documents that contain live code, equations, visualizations, and narrative text. They are a popular tool among data scientists and researchers but have also adapted for use in other fields, such as cybersecurity.
My Additions to the Blue-Jupyter
Many of the changes I've made are focused on automating the process of quickly looking for interesting new samples to investigate.
One addition to the notebook is the automated downloading of samples from Malware Bazaar. This can download a maximum of 100 samples continuously. Additional information is listed to highlight …
2022
-
Malware sandbox evasion in x64 assembly by checking ram size - Part 2
In the previous post, I explored a sandbox evasion technique that uses
GetPhysicallyInstalledSystemMemory
to check the size of the RAM of the machine. The idea behind this technique (MBC Technique ID: B0009.014) is that any value that is lower than 4GB may probably be a sandbox (to reduce costs). This information can then be used with other sandbox evasion techniques to confirm.For part 2 of this series, I'll be talking about an alternative Windows API function called
GlobalMemoryStatusEx
. This function is as straightforward as the first one, but requires the passing of a pointer to a C struct. This is significant because I'll be converting a working C code to x64 assembly so we can fully understand how it works under the hood.Using GlobalMemoryStatusEx
Here is an example of an implementation of
GlobalMemoryStatusEx
in C that we'll later be converting to x64 assembly.#include <stdio.h> #include …
-
Malware sandbox evasion in x64 assembly by checking ram size - Part 1
During my malware sandbox evasion research, I stumbled upon the Unprotect Project website. It is a community-contributed repository of evasion techniques used by malware. I saw that the the Checking Memory Size technique doesn't have a example snippet yet so I figured this would be a good first contribution to the project.
What to expect
In this blog post I'll be making a code snippet that showcases how to get the size of a computer's RAM in C. I will then convert this code into x64 assembly, mostly for me to practice writing in it, but also so that we can understand it better.
Checking the memory
The idea behind this evasion technique is simple. Most modern user machines will have at least around 4GB of RAM. Anything lower than that can be an indication that the machine is probably a sandbox (To save costs). While it's not exactly fool-proof …
-
Talking about Mitre's Malware Behavior Catalog
I gave a 10-minute lightning talk at the recently concluded Blackhat Middle East & Africa community meetup. The topic is about Mitre's Malware Behavior Catalog (MBC) framework and the existing tools for it. My reason for selecting this topic is because I feel that more people should know about Mitre's not-so-well-known project.
A brief overview
MBC is a framework made by Mitre, similar to ATT&CK, but focuses on malware. It lists down the common objectives and behaviors commonly seen in malware. The purpose is to have standardize reporting so that everyone would use the same definitions when writing and talking about malware. This also aids with analysis and correlation with other tools.
It has it's own matrix with malware objectives as headers for columns and an entry for each behavior. Each behavior then has a list of methods that explains how that behavior is achieved, example of malware that uses …
-
String anti-virus evasion in x64 assembly (Part 2)
In my last blog post, I discussed a way to hide parameter strings from being detected by an anti-virus. The solution was simple and it worked. However, it was incomplete as strings of function calls and loaded DLLs were still detectable in memory.
In this post I'll be talking about the other technique from the same blog post we were following before. It does a good job of explaining the concept which I'll be covering here too. I will also be writing the code in assembly as an added bonus, so we can better understand what goes on under the hood.
The problem
Let's revisit our code from the last time. We have two functions being called
ShellExecuteA
andExitProcess
.#include <windows.h> #include <shellapi.h> int main(void) { char ca_notepad[] = { 'n','o','t','e','p','a','d',0 }; ShellExecuteA(0, "open", ca_notepad, NULL, NULL, SW_SHOW); ExitProcess(0); }
Upon compiling …
-
String anti-virus evasion in x64 assembly (Part 1)
One of the features I implemented for my Remote Access Tool was an anti-virus evasion capability in the form of strings obfuscation. It wouldn't fool an EDR or a reverse engineer but it was quick to implement so I added it.
This was over a year ago. I decided to revisit this feature to try and understand it better and find out if it is actually effective.
What to expect
In this two-part blog post I will look into the following:
- Hiding argument strings
- Hiding API call strings
THe one you reading now is about the first one. I will be explaining how it's done in C and later convert it to x64 Windows Assembly so we can better understand what's happening under the hood.
Hiding function argument strings
I got the idea for this AV evasion technique from this blog post. The author posits that one part of an …
-
Converting a malware dropper to x64 assembly
In this post I'll be listing down lessons I learned while converting a simple malware dropper written in C to x64 assembly.
I started this project as a way to deepen my understanding of assembly so I could be better in malware development and reverse engineering (And also because I love coding in assembly and would always find an excuse to use it).
What to expect
I'll be going through sections of the C file and show the how it can be written accordingly in x64 Windows assembly. Take note, however, that the conversion is not one-to-one, meaning there are other ways of writing it. What I did was to structure the assembly code so that you can easily compare it with the C code while making sure that the end result will be the same.
I won't be covering the basics of assembly because this post does a better …
2021
-
Cyber Corp Case 2 Writeup - Part 3
The second case of the CyberCorp challenge on CyberDefenders.org is all about threat hunting. Created by @BlackMatter23 and his team, this challenge is based on a real-world attack so it is perfect for gaining practical experience in threat hunting.
This write-up is the third and final part of this walkthrough. You could read Part 1 here and Part 2 here.
Finding the post-reverse shell activity
Question 11. As a result of running a malicious code, which we talk about in questions 9 and 10, the attacker got a shell on the compromised host. Using this access, the attacker downloaded the Active Directory collection utility to the host in an encoded form. Specify a comma-separated, non-spaced link where the encoded version of the utility was downloaded and a SHA256 hash of the decoded version that was directly run by the attacker on the compromised host.
So from the question, I …
-
Cyber Corp Case 2 Writeup - Part 2
The second case of the CyberCorp challenge on CyberDefenders.org is all about threat hunting. Created by @BlackMatter23 and his team, this challenge is based on a real-world attack so it is perfect for gaining practical experience in threat hunting.
This writeup is part 2 out of multiple parts. You could read Part 1 here and Part 3 here.
Checking DNS Requests
Question 6. Specify the domain name of the resource from which the files mentioned in question 5 were supposedly downloaded as a result of malicious code execution.
This one is easy. Using the same date range from the previous question, I changed the query to
event_type:DNSReq
(where "DNSReq" is short for "DNS Requests").We could easily see a DNS record being queried, which is our answer to this question.
Finding the encoded executable code
Question 7. The first file downloaded (as a result of executing the code …
-
Cyber Corp Case 2 Writeup - Part 1
The second case of the CyberCorp challenge on CyberDefenders.org is all about threat hunting. Created by @BlackMatter23 and his team, this challenge is based on a real-world attack so it is perfect for gaining practical experience in threat hunting.
This writeup is part one out of multiple parts as I will be detailing my thought process and the steps I took for each question.
Edit: Part 2 and Part 3 is now out.
Understanding WMI Persistence
Question 1. The Threat Hunting process usually starts with the analyst making a hypothesis about a possible compromise vector or techniques used by an attacker. In this scenario, your initial hypothesis is as follows: "The attacker used the WMI subscription mechanism to obtain persistence within the infrastructure". Verify this hypothesis and find the name of the WMI Event Consumer used by the attacker to maintain his foothold.
So the question tells us that …
-
New Tool Preview: vATT&CK
I have released a new cybersecurity-related tool called vATT&CK (Visual ATT&CK). It is a relationship visualizer for the Mitre ATT&CK framework.
What the tool does is that it makes a visual map of the searched technique and all the related information. You can watch a video of the tool in action here.
Each node will be colored depending on it's category. The color legends is as follows:
- Pink - Related subtechniques
- Orange - Malware that uses the searched technique
- Red - Groups that uses the searched technique
- Blue - Tools that use the searched technique
- Yellow - Mitigations
This tool is still in development. I plan to add a number of improvements such as:
- Ability to click on nodes and then update the visual map
- Ability to search not just by technique, but also by other categories
I also plan on releasing a live demo of the tool very soon in the …
-
IOLI Crackme 0x04
I am continuing my reverse engineering review by tackling the IOLI crackmes by @pof. These are beginner friendly challenges that is perfect for newbies or for those who want to review the basics like me. Check out my writeups for 0x00, 0x01, 0x02, and 0x03.
Getting the password
Loading the program in IDA revealed something new. There is now a
_check
function that when opened looks more complicated than the previous challenges.The one thing that I immediately noticed is the call to the
_strlen
function similar to the previous challenge. This means that the length of the input string plays another important role.One curious thing is the condition that leads to the "Password Incorrect" block, as shown below.
call _strlen cmp [ebp+var_C], eax jnb short loc_401387
From the looks of it, the check will fail if
var_C
(Which is ourvar_counter
from the previous challenge) reaches the … -
Building my Virtual Cybersecurity Home Lab
I have recently realized that one part of cybersecurity that I am lacking basic knowledge on is networking. I honestly did not think it was important when I was starting. It was the reason why I skipped Network+ so I could take Security+ directly.
Now I know better.
Ever since my realization, I have taken steps to patch the holes in my knowledge. I've started taking courses and bought books. But one thing that has made the most impact is me building my very own "homelab".
I first came to know of the concept of homelabs from Reddit. To those unfamiliar, it is the practice of building a networked environment to gain practical knowledge in networking and IT. One way to do this is by making a virtual network.
And so, over the past month, I have been building my very own virtual homelab with a focus on integrating cybersecurity …
-
Making a RAT
A Remote Access Tool (RAT) is used to remotely access a computer. It has legitimate uses but it can also be used for malicious purposes. I've seen it used in malware I've analyzed and I've always been curious as to how it works.
I was following along the Handmade Hero project 1 when the topic about dynamic DLL loading came up. This is a process of dynamically loading a DLL at runtime which is useful if you want your program to check if a DLL is present in a system before loading it.
Two of the system calls that were discussed were LoadLibrary and GetProcAddress. These were familiar to me as I've seen them used on malware shellcode I analyzed in the past. I later learned that this is also used as an anti-virus evasion technique. I found this interesting.
Having learned how to do runtime DLL loading myself I …
-
Finding phished passwords on a scam site
Since my last post about my investigations of a Facebook phishing site, I have received several messages from friends asking me to check out other suspected phishing/scam sites. One of the most alarming out of them was this one where I was able to find the file where the scammer stores the phished usernames and passwords.
This particular phishing site conducts its operations like this:
- An ad is shown on Facebook, promising free coupons for famous fast food restaurants
- Clicking on the ad takes the user to a fake Facebook login page hosted on blogger.com
- Login page then sends phished username and passwords to a PHP file hosted on 000webhost
The phished passwords are then stored in a
.txt
file (blatantly named,victims.txt
), which is publicly accessible on an open directory. Getting to this directory involved following the scripts and the URLs used by the scammers. It's … -
Emprisa Maldoc Writeup
This is a writeup for Emprisa maldoc challenge that I made for CyberDefenders.org. You can play it here.
The very first thing that I do when confronted with a malicious document is to run it in a malware lab. This particular document, however, would not exhibit anything malicious on recent versions of Word.
A quick search of the hash on malware sandboxes would reveal that the document makes use of the CVE-2017-18822 vulnerability. This is a vulnerability that became known and was promptly patched around November of 2017.
The above details give us a hint on how to trigger the document, which is to run the maldoc on a version of Microsoft Word that doesn't have the patches that fix the vulnerability. The easiest way to do this is to boot up a new VM with a fresh install of Windows 7 and with updates disabled.
This new environment …
-
Investigating an FB phishing site
Last April 21, people were posting warnings about a suspicious Facebook post where your account will supposedly get hacked when you click it. From the discussions, I gathered that it is a classic phishing site scam. A very effective one too, because as soon as an account gets compromised the attacker logs in and tags the friends in the account allowing it to spread further. The news of this got big that even the PH CERT issued a security advisory on it.
I was just curious, I swear!
I wanted to see the phishing site for myself but I was unlucky and did not get tagged by anyone. So I reached out to people who did and I eventually got to this page shown below:
To a trained eye, one could easily see the obvious red flags. But how can one notice them if there is a very attention-catching image …
-
The Emprisa Maldoc Challenge
I was inspired to make my own CTF challenge after finishing Maldoc101 found at Cyberdefenders.org. The challenge I made is called Emprisa Maldoc and it is now up on their website.
Emprisa is based on a malicious document that I downloaded blindly from a malware sandbox. It used a relatively old but still interesting exploit that is still in use today. After researching more about it I came across a tool that can generate a malicious doc using the same exact exploit. This is when I got the idea to turn it into a challenge.
The challenge has 14 questions with increasing and varying difficulty. The challenge is targeted towards intermediate analysts who already have experience examining maldocs before. The goal is to reinforce the use of common malware analysis tools, but at the same time, teach players new things and techniques. It involves flexing muscles related to open …
-
IOLI Crackme 0x03
I am continuing my reverse engineering review by tackling the IOLI crackmes by @pof. These are beginner friendly challenges that is perfect for newbies or for those who want to review the basics like me. Check out my writeups for 0x00, 0x01, and 0x02.
Getting the password
After opening the program in IDA I immediately saw that the code is almost exactly as the one in challenge 0x02, with the exception of our expected
cmp
command being inside the_test
function.Reading through the code I realized that the password for this challenge is exactly the same as the previous one!
But what's this? The success and failure messages are all garbled? And plus, what is this other new function called
_shift
?A different kind of challenge
Opening up the
_shift
function shows us a short, but interesting looking program flow with two branches and one of the branches looping … -
Maldoc101 Writeup (Part 2)
This is part 2 of my writeup for the Maldoc101 challenge. Check out part 1 for the beginning of the analysis.
The next couple of lines does the same concatenating technique similar to the previous steps.
deaknaugthein = roubhaol.kaizseah.ControlTipText giakfeiw = deulsaocthuul + gooykadheoj + roubhaol.paerwagyouqumeid.ControlTipText + deaknaugthein queegthaen = giakfeiw + roubhaol.joefwoefcheaw
At the end of the code above
queegthaen
now contains the valueWin32_Process
+s
+tar
+tu
+P
. Or when combined creates the stringWin32_ProcessstartuP
which probably refers to this WMI class in the Microsoft docs.Note: This writeup appears to be incomplete. For the complete analysis, please refer to part 1 of this series.
-
Maldoc101 Writeup (Part 1)
This is part 1 out of 2 of my writeup for the Maldoc101 challenge made by Josh Stroschein (@jstrosch) and is currently playable at Cyberdefenders.Org. I've done some maldoc analysis before but this is the first time I'm writing about my approach.
There is also an already existing writeup about this challenge from the creator himself. You should check that out if you want a more detailed and focused writeup. This writeup is more from the perspective of someone relatively new to malware analysis. There's a lot more exploration and trial-and-error which, I hope, might give the reader a different view in how this kind of problem is approached.
The challenge
Name
MalDoc101 - Malicious Document
Description
It is common for threat actors to utilize living off the land (LOTL) techniques, such as the execution of PowerShell to further their attacks and transition from macro code. This challenge is intended …
-
IOLI Crackme 0x02
I am continuing my reverse engineering review by tackling the IOLI crackmes by @pof. These are beginner friendly challenges that is perfect for newbies or for those who want to review the basics like me. Check out my writeups for 0x00 and 0x01.
Getting the password
After the first two challenges I kinda know what to expect already so I skipped running the program and immediately loaded it in IDA.
So the lines leading to the comparison command now looks more complicated than before. We could easily see that there are some computations that happens thanks to the presence of
add
andimul
. Before those, we have two values (5Ah
and1ECh
) which we can easily guess are the values that will be worked on by these arithmetic functions.So going through the lines sequentially we can see that the two numbers are first added with
add [eax], edx
. Which … -
Introducing shcode2exe
[Edit: shcode2exe is now part of Remnux]
I've been playing around with Remnux and encountered a problem trying to get one of the tools to run properly. The tool is shellcode2exe, it is used to compile binary shellcode to a file so it can easily be debugged by a debugger.
When I checked out the code, I was surprised to find out how simple it is. Basically, what happens is that the inputted shellcode is added to a barebones assembly file using the
incbin
assembly instruction. From there, the file is then automatically compiled and linked.One big problem with the tool is that it needs to use Wine if it needs to run on Linux. I don't want such a huge dependency especially for my own malware analysis lab so I decided to write my own version which have led to the creation of
shcode2exe
.shcode2exe
While similar in …
-
IOLI Crackme 0x01
I am continuing my reverse engineering review by tackling the IOLI crackmes by @pof. These are beginner friendly challenges that is perfect for newbies or for those who want to review the basics like me. Check out my writeup for 0x00 here.
Getting the password
Of course, the first thing we do is run the program.
Just like last time, we opened up the program in IDA and focused on the part of the code that does the comparing of passwords.
cmp [ebp+var_4], 149Ah jz short loc_40137c
This seems easy enough.
Initially I entered
149A
as the password but this turned out to be incorrect. The reason for this is becausescanf
was passed a format of "%d".mov [esp+18h+Format], offset aD ; "%d" call _scanf
This means that the input it expects is actually a decimal integer. So converting
149A
to decimal results in5274 …
-
IOLI Crackme 0x00
I am re-familiarizing myself with reverse engineering again by going through some simple crackme challenges. This one is called the IOLI Crackmes by pof. The goal is to find the correct password and also to patch it so that it can accept any input and still show that it's correct.
Getting the password
Running the program shows a password prompt.
Of course, randomly entering passwords is going to be a waste of time so I opened up IDA to look at its code.
I knew that whatever password I enter in the program would be checked against the actual password. This is the part of the program that I should focus on so I scanned the code and found this:
mov [esp+38h+Str2], offset Str2; "250382" mov [esp+38h+Format], eax; call _strcmp
And just from these few lines alone I already knew what the password is …
2020
-
Hunt the Kingdom CTF Challenge
TLDR: Participated in a blue team CTF, had a lot of fun, looking forward for more
Yesterday I participated in the GuideM "Hunt the Kingdom" CTF challenge. It served as the final activity at the end of the "Cyber Defense and Threat Hunting" course.
I was looking forward to this CTF, especially after my awesome experience with the Red Team Village CTF at Defcon. This one is centered on the Blue Team side, and I was curious as to how it will play out.
The Preparation
I took one whole day to study and prepare. I went through all our slides and have written down the important concepts and commands to an org file. This is important because I wanted them to be easily searchable, which helped a lot during the challenge.
I also did research about the Hunt the Kingdom challenge itself. There weren't much information online about it …
-
My experience with manufacturing printed circuit boards
I've done a lot of electronics projects already, all of them were painstakingly hand-soldered on a perfboard. I actually like this approach for quick prototyping, and plus, I've also grown fond of how "raw" it looks like. In spite of this, I've always been curious and interested in having my own printed PCB. I remember designing one for my TIRO vibrating watch but I never pushed through with it because I wasn't confident with what I've made.
I really like the raw, almost electronic-punk look of my work
A couple of months ago I got an email from PCBWay asking if I was interested in trying out their PCB manufacturing service. The email from PCBWay re-ignited this interest in having a PCB made. The problem is I didn't have a PCB design that I built myself that I knew was going to work. My best option was the "ESPBoy project …
-
CovidScammers writeup (Defcon RTV CTF)
I joined the Defcon Red Team Village CTF because I was curious about it and I wanted to test out the skills that I have gained playing with CTF sites like overthewire.org and vulnhub. I knew that the challenges won't be easy, but thankfully, I was able to join up with other newbies who were willing to give it a go and learn with each other.
Unfortunately, I fell asleep just before the CTF started and when I woke up all the easy challenges were already solved by my team members. There was one easy challenge that was still open on the CovidScammers category, so I quickly got started to solving that.
Free Flag (and binary) [1 point]
You've been contacted by a high-end but morally ambiguous finance company (unhackable-bitcoin-wallet.com) to investigate a data breach. The box in question is a mail server in their internal network, a …
-
Study notes: MAC Spoofing
Study notes are my personal research notes on certain topics that interests me.
Any network capable device has a unique factory-assigned Media Access Control (MAC) address. Users have no way to change the MAC address but it can be done. However, it is possible to mask the MAC address and have it show a different value. This is called MAC spoofing.
There are legitimate uses for MAC spoofing. For example, there may be certain applications that require a particular MAC address to work, or maybe your ISP expects a certain MAC address to connect to the network. MAC spoofing is largely used for illegitimate uses, like circumventing an access control list or getting past a filter on a wireless network.
Changing MAC Address via ifconfig
In Linux we could use
ifconfig
to change the MAC address.To view the current MAC address:
$ ifconfig
The current MAC address is
08:00 …
-
Chicken-Scheme FFI Examples
I'm currently working on refactoring the FFI implementation for the Rebel Game Engine. It was previously written using the Bind chicken egg but I wanted to have more control over the implementation by using the low level foreign functions.
To help me better understand I made some examples that has the basic FFI implementations that I'll be needing for my project.
foreign-lambda example
Let's say we have a structure
Vec3
and a functionVec3Create
that we want to access from chicken-scheme.typedef struct Vec3 { float x; float y; float z; } Vec3; Vec3* Vec3Create(float x, float y, float z) { Vec3* v = (Vec3*)malloc(sizeof(Vec3)); v->x = x; v->y = y; v->z = z; return v; }
We could use
foreign-lambda
to bind to the function:(define vec3_create (foreign-lambda (c-pointer (struct "Vec3")) ; Return type, a pointer to a struct object of Vec3 "Vec3Create" ; Name fo the function float float float)) ; The …
-
#5 - Switching from C/C++ to C
After the recent changes to the lisp side of my engine, I took some time to review the C/C++ side. You'll notice that I have written C/C++ and that's because my codebase uses both of them.
When I started my project, I initially intended for it to use just pure C, as this is the one I'm more familiar with. But over time some C++ features crept in. Features like namespacess, bools, and function overloading proved to be useful so I kept using them. Now my code uses C concepts with new nifty C++ features.
Now, I could have just continued with this approach. It works, after all. But I wondered if I should just stick to C and drop C++ altogether. My thinking is that sticking with just one language would make the code simpler as I only have to use it's subset of features. I know …
-
#4 - Following Lispy conventions
I was adding new Lisp functions to my game engine when I noticed that I had functions that had a naming scheme that were inconsistent with others. For example, I had ones that create objects like sprite_create and shader_create but this one function I named make_vec3. I proceeded to rename make_vec3 to vec3_create. Not only is it consistent with other names but it made me realize that having a pattern of object_verb makes it easy to parse the function and what it does.
This made me wonder if there are other ways I could improve which led me to this page about variable naming conventions for Scheme. I learned that the language employs a rather effective yet simple naming convention for functions and variables. I've noticed them before but never really thought about their usefulness.
For example, adding a ? prefix easily indicates that the function, when called, will always return …
-
#3 - Rebel Game Engine now works on different platforms
After finishing the integration of Chicken-scheme scripting for my custom game engine I decided I wanted to tackle another hard problem, and that is making it cross-platform. At the very least, my engine should be able to deploy to Linux, Windows, and MacOSX.
It might seem silly to be working on this while the engine is still in its early stages, but I think it is better to get this out of the way before the codebase becomes huge. With a small codebase I was able to easily identify the causes of the problems as I was porting them.
It still wasn't a walk in the park, however. Being inexperienced with developing C programs on other platforms (I've only done it mostly in Linux) I had to do research and do a lot of trial and error. I learned so much about cross-compilers, portable makefiles, and the quirks of different …
-
#2 - Implemented basic Scheme scripting for Rebel Game Engine
When I first learned about Chibi, an embeddable scheme that allows scripting on C programs, I immediately tried it out on my game engine. I was able to make it work with my existing APIs but I kept on running against segfaults and memory issues. The community was helpful in answering my questions as I tried to track down the cause of the bug, but I eventually gave up out of frustration.
I then learned about Chicken Scheme, a somewhat competitor to Chibi that does the same thing but with a larger community and more documentation. I checked it out and liked it so I went ahead and implemented it.
Thankfully I have not experienced any segfaults anymore. It's not because Chicken is better (I don't know well enough of the two to make a good comparison) but because I've come to better understand how to properly structure my code …
-
#1 - Thinking of adding Lisp to my custom game engine
I've long wondered if I should add a scripting language to my game engine. I know that most game engines could do without such a feature but I just recently came across Chibi-Scheme, a library that allows the use of Scheme lisp scripting for C programs.
I like Lisp. I use it a lot when customizing my Emacs environment (using ELisp). There's something about it's syntax and different way to structure programs that appeals to my programmer brain. I've toyed with other Lisp flavors but never had a strong enough reason to continue using them. With Chibi-scheme I may have found that reason.
I am aware that Lisp is not as widespread as Lua or Javascript. And that choosing it might limit the number of potential people to try out my game engine. But as I've been telling myself over and over, this is a self-learning project. So it's okay …
-
Making Unity beep after scripts finish reloading
Our latest game, HistoHunters, has grown into a really big project that compilation now takes a really long time. Longer than no sane programmer wants it to be. It has gotten so bad that changing a single file would take about a minute for recompilation!
Thankfully, I have managed to shorten this wait time through the use of assembly definitions. If you have a big Unity project and compile times are slow, this is the solution to that. Just for kicks I also purchased an SSD and that also helped reduce compile times (Not much as the assembly definitions though).
However, in spite of these changes compiling still takes a few seconds to reload scripts. This seems to be the lowest it could go. While this is definitely better, I can't help but feel that the seconds spent waiting is wasted.
I recently got the idea of having Unity inform …
2018
-
Opening Unity Script Files in Emacs
I've recently embarked on a mission to fully integrate Emacs with my Unity game development environment. One feature that I wanted to have is the ability to open Unity scripts and text-based files in Emacs instead of MonoDevelop. This is an easy task for supported external editors but for those who aren't (Like Emacs), doing something like this is a bit tricky.
Setting emacsclient as the external editor works in opening the files but the line number is not passed at all (Or is not received by emacs. Seems to be a bug). This means that opening files in the Project Window works but you would not be able to to jump to lines that have errors from the Console. This, of course, is unacceptable.
I've tried a number of different solutions. A lot of them are hacky but clever. There was this one option of setting a Sublime Text …
2017
-
Chef Wars Postmortem -- What Went Right: Risk Adjusted Technical Estimates
Note: This is from a series of articles that outlines the things I've learned while making Chef Wars for 2+ years.
TL;DR
- We used a risk adjusted estimation system that produces near accurate estimates we can confidently rely on.
I usually dreaded being asked how long a programming task will take. I always seem to have the knack to overshoot no matter how hard I try. This is an all too common scenario that programmers face and is something that is considered to be a difficult, if not impossible, problem to solve.
This all changed when I was introduced to a helpful system that helps in producing estimates that are "accurate enough". I don't think it has a name yet but my colleagues who introduced me to it says that they got it from a Gamasutra article by Eric Preisz of Garage Games. Since then I've used this system …
-
Chef Wars Postmortem -- What went wrong: Optimizing too early and too late
Note: This is from a series of articles that outlines the things I've learned while making Chef Wars for 2+ years.
TLDR
- There is more to the saying that "premature optimization is the root of all evil".
- Instead of asking WHEN to optimize, it is more important to ask WHAT and HOW to optimize.
It is a well known adage among programmers that premature optimization is the root of all evil. If this is true then I must have been very close to the devil himself.
During the early months of development on Chef Wars I did my best to optimize my code as much as possible. We were making a big game and I wanted to have a stable foundation to build our game on. I obsessed over lots of things from the interconnection of the various systems to folder structures. I was happy with all that I've built …
-
Chef Wars Postmortem -- What went right: Having a Universe File
Note: This is from a series of articles that outlines the things I've learned while making Chef Wars for 2+ years.
TLDR
- All data in our game is contained in one excel file we call the "Universe".
- Prototypes can be done on the Universe excel file itself
- Iteration is easier as we only need to change one file.
- We made a system that downloads changes from our server so players don't need to update their builds.
Before we started development on Chef Wars, Cliff, my co-founder and game designer for the team, already had pages of spreadsheets containing important values in the game. It's kinda like a game design document but in the form of tables, columns, and rows. This "Universe" file contained everything from stats, dialogue, competitions, locations, chefs, and enemies just to name a few.
*This file definitely gives a hint on what type of guy Cliff is …
-
Temp Solution For When Text Copying Does Not Work in Emacs Under Windows Subsytem for Linux
One of the problems I was having with my Emacs environment under WSL (Windows Subsystem for Linux, aka. Bash On Windows) is that I could not copy text from WSL Emacs to other Windows applications. Copy and pasting from Windows to Emacs works without any problems so it's weird it does not work the other way around.
I tried a lot of solutions from Google but none of them seem to work. There was an emacs package called simpleclip that worked but the results were not consistent.
I then realized that a temporary solution would be to make use of Windows' clip.exe command line utility which can bme seen below.
(defun arebel-set-clipboard-data (str-val) "Puts text in Windows clipboard. Copying to Windows from WSL does not work on my end so this one is a temporary solution. This function is called from within the simpleclip package when copy or bgcopy …
-
Converting org-journal entry to org-page post
Since my recent switch from Wordpress to org-page I wanted a way to convert my org-journal entries to org-page posts. Instead of copying each entry by hand and pasting to an org-page new page buffer I decided to make an elisp code that would do it automatically which can be seen below:
(defun arebel-org-journal-entry-to-org-page-post () "Copy the org-journal entry at point and then convert it to a org-page new post buffer." (interactive) (if (eq 'org-journal-mode major-mode) (let ((headline-text (nth 4 (org-heading-components))) (entry-text (org-get-entry))) (funcall-interactively 'op/new-post "blog" (concat (buffer-name) "-" headline-text)) (goto-char (point-max)) (insert entry-text)) (message "This function can only be called inside org-journal-mode.")) )
The function is simple and uses functions from org-mode and org-page.
- First, it checks if the current buffer is in org-journal-mode
- Then it gets the headline text and entry texts
- It then calls op/new-post. It does it interactively so that it will trigger the prompts needed to …
-
Converting org-journal entry to org-page post
I needed a way to minify JSON files from Emacs so I made the short function below.
(defun arebel-minify-buffer-contents() "Minifies the buffer contents by removing whitespaces." (interactive) (delete-whitespace-rectangle (point-min) (point-max)) (mark-whole-buffer) (goto-char (point-min)) (while (search-forward "\n" nil t) (replace-match "" nil t)))
The function is very simple. First it deletes the whitespaces for the whole current buffer then removes every newline.
This effectively turns this:
{ "glossary": { "title": "example glossary", "GlossDiv": { "title": "S", "GlossList": { "GlossEntry": { "ID": "SGML", "SortAs": "SGML", "GlossTerm": "Standard Generalized Markup Language", "Acronym": "SGML", "Abbrev": "ISO 8879:1986", "GlossDef": { "para": "A meta-markup language, used to create markup languages such as DocBook.", "GlossSeeAlso": ["GML", "XML"] }, "GlossSee": "markup" } } } } }
To this:
{"glossary": {"title": "example glossary","GlossDiv": {"title": "S","GlossList": {"GlossEntry": {"ID": "SGML","SortAs": "SGML","GlossTerm": "Standard Generalized Markup Language","Acronym": "SGML","Abbrev": "ISO 8879:1986","GlossDef": {"para": "A meta-markup language, used to create markup languages such as DocBook.","GlossSeeAlso": ["GML", "XML"]},"GlossSee": "markup …