Tuesday, December 30, 2014

Removing Context Menu Entries in Windows

If you install a lot of programs, you may find that your context menu (the list that appears when you right-click) has a bunch of junk on it or takes a few seconds to load. Fortunately, it's pretty simple to clean up the global context menu.

Open regedit with Windows+R "regedit" and accept the UAC confirmation. Navigate to HKEY_CLASSES_ROOT, then the folder whose name is a single asterisk "*", then "shellex", then expand the folder names "ContextMenuHandlers". Every subfolder (subkey) of that is one program's group of entries that shows up on your context menu everywhere. Simply right-click and choose Delete on an entry to remove it. (If there is an entry that looks like a mash of hexadecimal characters in curly braces, some app developer tried to register entries manually and misunderstood how this key works. Those entries can be deleted.)

Fun fact: using the .NET Framework in a context menu handler is a great way to produce insane slowdowns whenever the user right-clicks. Developers, please don't. .NET is great - I love it - but loading the CLR takes what is an unacceptable length of time for right-click responsiveness.

Monday, December 29, 2014

Accessing Windows Storage Volumes by GUID

Suppose you have a storage volume whose drive letter is variable, but you need a consistent means of addressing it. (Like a flash drive that has something you need to access from a batch file.) You could use the whole WMIC-forloop-findstr business to get the letter, but then you have environment variables that need to be cleaned up. Or maybe you just don't want to deal with that whole thing and would rather just access the drive by a unique intrinsic property of it.

You can get the drive's GUID by typing "mountvol" at a command prompt. At the end of its help spew, it tells you all the volumes that the system sees at the moment:

Right click in the window and choose Mark, highlight the whole GUID line (the \\?\Volume{...}\ thing), and hit Enter to copy it. This path can sort of be used as a directory, with the following major limitations:

  • You can't cd to it (even with PowerShell)
  • You can't mount it with net use
  • You can't get to it with pushd
  • Almost no application will open files on it
The only thing you can reliably do is dir it (adding a second backslash to the end if you want its root directory) and copy files from it. Copying to and from it, however, lets you do basically anything - just copy a file off, edit it however you want, and copy it back it.

Sunday, December 28, 2014

Abiathar Confidential - GameMaps with VeriMaps Signature Format

Abiathar, as of v2.2, includes the VeriMaps feature, which alters the format of the emitted GameMaps file to some degree. I am describing its format here so that any other editors or tools can read and write the modified format correctly.


First, if a GameMaps file is an Abiathar VeriMaps file, its first eight bytes are "FleexRSA". (If that signature isn't there, no special considerations are necessary for 100% compatibility with Abiathar.) The signature is immediately followed (there's no null terminator after "FleexRSA") by the name of the signer, which is ended with a null. After that is the 128-byte RSA signature.

Before parsing any level data, read the entire rest of the file (starting immediately after the signature) into a buffer. Append the name of the signer to this string:

https://dl.dropboxusercontent.com/u/3771470/Abiathar/VeriMaps/

And add ".acert" to the end to get the URL of the user's public key. (You can test for connection using "VeriMaps.txt" in that directory, which should contain the string "Abiathar".) The first line of that file is the user's distinction/title or "NUL" if they have no distinction. The second line is the XML representation of a .NET RSAParameters object that can be created like this:

Dim sFile As New IO.StreamReader(Path)
Dim distinction = sFile.ReadLine
Dim rsa = Security.Cryptography.RSA.Create()
rsa.FromXmlString(sFile.ReadToEnd)
sFile.Close()
Dim rsaParams = rsa.ExportParameters(False)

Compute the SHA-512 hash of the GameMaps file data. Compare it to the signed version that came with the file using this function:

Public Function CheckSignature(SignedHash As Byte(), _
 Hash As Byte(), Cert As RSAParameters) As Boolean

 Dim rsa As New RSACryptoServiceProvider
 rsa.ImportParameters(Cert)
 Dim deform As New RSAPKCS1SignatureDeformatter(rsa)
 deform.SetHashAlgorithm("SHA512")
 Return deform.VerifySignature(Hash, SignedHash)
End Function

To create signed VeriMaps files, use an ASIGN (signing certificate) file provided by the user. The first line is the user's name; the second is the XML RSAParameters with private key data included. After writing the main GameMaps data region, calculate its hash and sign it using RSAPKCS1SignatureFormatter.

Saturday, December 27, 2014

DPAPI Doesn't Protect Much Data

You may have heard of the Windows Data Protection API, or DPAPI for short. Unfortunately, it doesn't protect much unless you're on a computer that people aren't using and don't have any access to, like a server.

The thing is, DPAPI encrypts the "protected" data with a per-user key that is kept secret by the OS kernel. This sounds really nice until you find out that every process running as the user can utilize DPAPI to encrypt and decrypt data belonging to that user. What's more, physical access to the computer can be exploited to get the machine key, which can be used to decrypt the user keys, which can be used to decrypt any data belonging to them. Data can also be DPAPI-encrypted with the system key, which allows any application running on the computer to decrypt it.

The situation is made slightly better by the possibility of adding "entropy" to the encryption. Of course, that must also be used to decrypt the data. What you then get is a chicken-and-egg problem: it's impossible to securely store the second key because you have no way of safely encrypting it.

So, DPAPI might be a tiny bit more secure than plain text - it might not be immediately obvious to an attacker that you're using it - but it's impossible to keep a secret inside one machine.

Friday, December 26, 2014

Reading SQLite Databases from .NET

Today, I needed to use .NET to read data in an SQLite database. I found a really nice open-source project for doing that, called System.Data.SQLite. However, it took me a while to figure out how to get it working after deployment (i.e. not run from Visual Studio).

I kept getting BadImageFormatException and other errors like side-by-side configuration issues that are utterly incomprehensible to me as a managed-only developer. It turns out that the SQLite DLL is really touchy about .NET version and processor architecture, which makes sense considering it's a mixed mode (managed and native together) assembly. It's super important that you get the right binary package - I recommend the "Precompiled Binaries for 32-bit Windows (.NET Framework 4.0)" download because 64-bit OS's can run 32-bit programs and .NET 4.0 is usable on Windows XP and later.

In your project settings in Visual Studio, set your project to compile to x86 only (an option in the Compile tab). If you need 64-bitness, use that only and deploy the x64 version of SQLite.

Then, you have to keep the manifests and config files with your compiled programs when you deploy. The stuff about the VSHOST process attachment and the PDB's can be removed, but all the other supplementary stuff has to stay for SQLite to figure out how to run.

Once you have it compiling and running deployed, the SQLiteConnection and SQLiteAdapter class can be used just like other ADO.NET providers to get your data into DataTable instances.

Thursday, December 25, 2014

How to Write and Compile USB Rubber Ducky Scripts

I just acquired a USB Rubber Ducky, a keystroke injector for all manner of computing devices. It took a bit of research to pick up all the knowledge necessary to get started with it, so I have written a short compilation here.

First, you'll need to remove the MicroSD card from the device, which is surprisingly difficult. Wiggle the card around a little and try to slide it out with your thumb. After the first time, it gets easier. Insert the card into your computer. If you don't have a MicroSD slot, use a MicroSD-to-USB flash-drive-ifier adapter, which may have come with your Rubber Ducky.

You'll find on the card a single file called inject.bin. This is the payload that will be executed when you plug the device into a computer. It's a proprietary binary format, so it's not easily modified directly. Instead, you write a text file in DuckyScript, which is a fairly intuitive scripting language. This text file is then compiled into the inject.bin by DuckEncode, a cross-platform executable JAR file.

I recommend creating a Windows batch file to do the compilation, since JAR files can't be drop targets by default. I made a compile.bat file that is just this line:

java -jar duckencode.jar -i %1 -o inject.bin

Place that in the same directory as the DuckEncode,jar you downloaded earlier. You can then drop any DuckyScript file onto the batch file and it will emit inject.bin from the script, which you can then move onto the device.

DELAY 2000
GUI r
DELAY 200
STRING notepad
ENTER
DELAY 400
STRING Hello!

Wednesday, December 24, 2014

FMod - v2.3

I made a small adjustment to the Dreams levels loading code that will allow Abiathar to automatically fill in the compressed level header length if that section of the map header is missing or truncated (probably by The Omegamatic). This makes the FxTomDMh utility obsolete.

After making that change, I wrote up some documentation for v2.3 (as I have decided to call this release), wrote a changelog/release post on PCKF, and pushed it out with the auto-updater.

Tuesday, December 23, 2014

FMod - Helpful

One serious problem that I had identified with Abiathar was the lack of discoverability of its amazing features. The "did you know?" tips on the tools helped a little, but I can't be throwing them around all the time and they are also too small to provide detailed guides. People don't want to download and read a 40-page PDF to learn about this stuff; they just want to use whatever tool they just opened.

So, I removed most of the tip pop-ups from the tools (all the ones that appear at start-up are still there) and created a new panel for contextual help. Each tool can report what commands it can receive at a given point and provide any instructions that the user might need. The entire thing can easily be switched on or off at any time by pressing the question mark key or choosing Help | Contextual. It can be set to be turned on at startup through a config entry under DefaultViewSettings. I added contextual help for all the tools; I'm guessing it makes using them a lot easier for people who don't have the code right in front of them.

(The tool tips that were left on the Tile Property Modifier and Tile Instance Remapper say something to the effect of "this tool is really hard to use; you probably want to enable contextual help.")

I also identified and fixed several bugs while doing this:

  • The "did you know?" pop-up looked really out-of-place, being the normal Windows Forms colors on top of the intense blue on black of the initial screen.
  • The tool status text was lost when switching to the tile palette and back.
  • The Tile Property Modifier left its status text behind after being canceled.
  • The Tile Property Modified left the animation target highlight behind only when switching to the Palette Copier.
  • The Tile Instance Remapper was extraordinarily inconvenient to use because it reset the find buffer whenever plane states were changed.
All these changes might be worthy of the version number "2.3" rather than "2.2.1", but I'm not sure yet. What I am sure of is that these changes make using Abiathar a whole lot easier for new users.

Monday, December 22, 2014

FMod - Did You Know?

Today, in addition to starting my Music Appreciation winterim class, I continued working on what will be the v2.2.1 Abiathar update. From talking with an important user on IRC, I discovered some problems with the Patches dialog, which I thought was extremely simple! Apparently, his patch file's size exceeds the TextBox default max length of 32KB, so I increased the limit to 1MB, which should be more than enough for everyone. Also, the TextBox control does not by default make Ctrl+A select all, so I had to add that feature manually.

Then, I actually did something with the "did you know" tip boxes that I implemented yesterday. I wrote a collection of helpful tips, one of which is randomly chosen and displayed at start-up. Since the overlay is actually another form, I had to make keypresses on it forward to the main form. Then I discovered that when it passes the handling onto the main form, the dialog boxes created in the press handling are owned by the tip form, which destroys itself after a few seconds, taking the dialogs with it. So, I had to manually pass the main form to every ShowDialog call.

Some of the tools also show tips when they are first activated. Unfortunately, some of them are so extraordinarily complicated that useful help can only be found in the documentation. For those, I may need to pop off a live assistance pane.

Sunday, December 21, 2014

FMod - Fix the Overwrite Bug

Through thought-experiments, I discovered what is probably a very annoying bug in Abiathar. If all the sounds are exported and then some IMF songs are imported with Song Mappings, those later changes will be lost if the full sound set is re-imported (unless the IMF song there was also updated).

I added a last-modified date for the IMF songs, stored in the dependency file. When a song is added modified with Song Mappings, the current time is written to the chunk's entry in this table. When importing the full sound set, the file's last-modified date is checked against that of the existing song. If the file is not newer than the existing song, the data is reused from the old audio resource before it is overwritten by the recompiled version. I also added a warning to the Audio Files dialog that should prevent people from accidentally blowing away their song mappings and extra songs; the mistake was easy enough to make that I did it myself.

I also found a subtle yet major problem with the Freeform Tile Placer that made it behave exactly like the Tile Tweaker. Somewhere along the way, its tool initializer had been changed to only listen for mouse movements if a certain Keen:Next emulation feature was enabled. That was easy enough to fix, and I'm surprised nobody noticed. (Though the main person who wanted it always uses all the Keen:Next emulation features.)

Finally, I built infrastructure for helpful and hopefully unobtrusive "did you know?" tips.

Friday, December 19, 2014

Cryptographic Verification of Backwards Time Travel

In every sci-fi show where a character goes back in time, a whole bunch of time is spent convincing everyone that he is indeed from the future. In the unlikely event that this sort of thing happens in real life, we should have a way to quickly determine whether someone is truly from the future without all the hassles we see on TV.

I propose a small government ministry, possibly a service or subsidiary of NIST, whose sole purpose is to generate, store, and release asymmetric-cryptographic keys. Each day, this agency generates several asymmetric key pairs and publishes all the public keys. The private keys are kept private for a time, then released after the following intervals:
  • 1 day
  • 3 days
  • 1 week
  • 1 month
  • 6 months
  • 1 year
  • 2 years
  • 5 years
  • 20 years
  • 50 years
  • 100 years
  • 200 years
Everybody should keep (or have a device that keeps) the most recently released private key for each day. Upon being transported back in time, the traveler can use the private key for the day in which he finds himself to encrypt a challenge text from those who wish to verify his traveling. The challengers can then decrypt the challenge text with the day's public key, and if the decryption succeeds, the traveler holds the private key and did indeed go back in time. It is possible to verify about how far in the future the traveler was by the last private key he has for the day.

The entire system relies on the security and longevity of the time service. Everybody would have to carry their key management device with them all the time, but it could be as unobtrusive as a small flashlight on a key ring. Of course, the entire idea of time travel is kind of far-fetched, so implementing this system be entirely pointless. You never know, though...

Thursday, December 18, 2014

Robotics - Ramp Reassemble

We finally got the linear bearings 3D printed and attached. (That actually happened on the meeting last Saturday, which I could not attend.) The builders worked on mounting the lift assembly to the robot and tested operating the lift with string.

Meanwhile, I and several other non-engineers worked on fixing the ramp that had been assembled inside-out and backwards. We went down to the local hardware store and bought longer rivets and long screws for the builders. With the new rivets, we were able to - after a good deal of spatial finagling - rivet the pieces of the ramp together. It actually took four people and almost an hour of working together to make it happen.

We started attaching the side pieces to the ramp, but we ran out of time and didn't have all the brackets ready.

Wednesday, December 17, 2014

Speeding up Throttled Download Sites

I'm sure you've experienced the free download sites that throw boatloads of ads in your face and make your downloads excruciatingly slow unless you pay a possibly-not-so-small amount of money to upgrade to the "premium" experience. I've discovered an interesting method of speeding up these throttled downloads, at least a little bit:

Close the tab that created the download. In my experience, once the tab is closed and the connection is severed to the controlling web site, the download speeds up. The only reason I can imagine for this is that they don't want to risk giving their paying customers slow speeds, so once the HTTP session is lost, the speed goes back to normal. Of course, it should be very easy to have different servers for the different groups, so maybe it's just a placebo. Try it though - it might help somewhere.

Tuesday, December 16, 2014

Internet Routing Issues

Something has gone wrong with an upstream router, and I am only able to access a few of the sites I need to use for my normal operations. I can't find a pattern in the sites that work and those that don't. They all resolve normally in DNS, but I can't push any traffic through to them. I've power-cycled my router, but problems persist. Mediacom tech support could not identify the problem, and it has not been fixed in the three hours in which they said it would be.

Fortunately, I can access all important sites through proxies and onion-routing networks. It's really inconvenient, though, and I hope Mediacom fixes it soon.

Saturday, December 13, 2014

Removing Mysterious BlockAndSurf Ads from Chrome

I recently had the pleasure(?) of cleaning a number of adware programs off a Windows 7 laptop, including BlockAndSurf, sometimes known as Block-N-Surf, Re-Markable, or a whole host of other names. I used the ever-helpful MalwareBytes Anti-Malware and newly-discovered Hitman Pro to purge most of the horribleness from the machine, but the BlockAndSurf ads still lingered on many pages even though there was no Chrome extension for it or any other auto-start entry. It turns out that BlockAndSurf infects Chrome in some deep way that requires a complete uninstallation (remove browsing preferences, history, everything) and hosing of the directories in which it kept program files. After I ripped out every trace of Chrome and re-installed it, the ads were finally gone.

Friday, December 12, 2014

Managing User Accounts in Windows 8 Without the Metro

I am personally not a fan of the presence of two divergent Control Panel-ish areas in Windows 8. I just want my normal desktop Control Panel that has all the functionality I could ever want. Unfortunately, the Metro PC Settings app seems to be the default for managing "easy" settings, which apparently includes user accounts. There's still the User Accounts applet in Control Panel, but to add new users you have to go to PC Settings.
No, I want to add a new user right here.
As a side note, in the configuration page for a user account in this applet, there is still a link to one of the most pointless dialogs in Windows:
You can literally do nothing from here besides go where you already are.
("Change Type" just lets you choose between a local account and... nothing. The other option, "roaming", is always disabled unless you're on a domain with roaming user profiles.)

So, rather than dealing with that or PC Settings, I choose to use the administrative tools! (Woo, enterprise software.) If you're using Windows 8.1, right-click the Start button and choose Computer Management. Otherwise, it can be found under Administrative Tools in the desktop Control Panel. Under Local users and Groups, click the Users folder to see all the users of the computer. Add a new one with Action | New User. To promote a user to administrator, open its properties and add the Administrators group to the Member Of list.

Metro avoided and admin tools used. Nice!

Thursday, December 11, 2014

Where to Find WIM Files for Deployment

It took me a long time to figure this out, but the Microsoft-proprietary WIM installation image files can only be acquired from the OS install discs. If you're deploying Windows 7, insert the Windows 7 disc that you have and pull the Boot.wim and Install.wim out of the "sources" folder. If you have an ISO of the install disc, just extract those files with your archive management program of choice.

Wednesday, December 10, 2014

Robotics - Solder It

Since it's a lack of lifting mechanism that's holding up our progress in robotics, we decided to start working on one despite not having the materials we need. We were expecting to have the linear slides 3D printed by now, but the facilitator of that is sick. So, we pulled out the contraptions that we started making at the last meet and tried to replicate them. We applied ThreadLock to the screws because there isn't a place to put nuts. These small assemblies were applied to the channels we have, and they seem to be doing a decent job of holding it together. We have yet to see whether it can be telescoped out by a motor.

Last week, we discovered that our field was set up backwards. Today, we discovered that the ramp's walls were reversed as well (to accommodate our misconception of the field layout). Not only that, we put the ramp plastic pieces together upside-down, so the arrangement of rivet holes was totally wrong. We got a drill and took the entire ramp apart - it was all wrong. We started putting it together the right way, but we need to find longer rivets.

Finally, I and one other member with little to do once the ramp was disassembled found the large bags of LEDs (that we ordered last year to use all our budget) and started soldering them to wires as practice and for fun. We didn't know that the length of the wires coming out of the LED mattered, so it was trial and error figuring out which way the circuit needed to go. We hooked it up to a triple-A battery from my calculator to see a slight red glow.

Tuesday, December 9, 2014

Why "Server Operators" and "Backup Operators" are Equivalent to "Administrators"

Alternatively titled "Why SeRestorePrivilege Should Be Called SeTakeOverTheDomainPrivilege"

On Windows domains, there are special built-in groups called Server Operators and Backup Operators. Backup Operators are allowed to log on to domain controllers and access all the files everywhere for the purpose of backing them up. Server Operators are glorified Backup Operators, except that Server Operators can format hard drives, manage some services, and shut down the server remotely.

Both these groups hold SeBackupPrivilege and SeRestorePrivilege. SeBackupPrivilege, when activated by the user, is essentially an overriding Allow entry on GENERIC_READ for every DACL ever. In other words, holders of this privilege can read and copy every single file, including the full Active Directory or SAM databases. Depending on your credential storage hash strength, you may have handed all the passwords over to the Operators.

More importantly, SeRestorePrivilege allows the holder to write to anything anywhere, update any DACLs, and set any file metadata. This could be abused to lay a logon script trap for a full Administrator, or just use the sethc.exe trick to elevate to SYSTEM on a domain controller and do whatever to the Active Directory. Registering services to run as SYSTEM would work equally well.

As a side note, the Print Operators group has SeLoadDriverPrivilege, which allows a user to register user- or kernel-mode drivers. That ability opens up any number of system takeover avenues, so Print Operators are also just Administrators who haven't realized it yet.

You can learn all about the built-in groups and their privileges in TechNet's "Default groups: Active Directory" article.

So, you might want to reconsider adding semi-trusted people to these groups. They're pretty powerful once they realize it - it's not a large jump from any type of Operator to Administrator.

Monday, December 8, 2014

Converting a Physical Computer into a Virtual Machine

I was given the task today of taking a physical server and jamming it into a virtual machine that can be easily transported and backed up. Fortunately, this process is easier than the reverse.

VMWare Player
If you want to make a VMWare Player virtual machine, you'll need to use Norton Ghost, which comes on the free Win8.1SE boot disc. Burn that ISO to a DVD and use it to boot the machine, which may take up to 10 minutes. You'll need a huge flash drive, an extra hard drive, or a bunch of network storage to put the disk image in. Run Ghost from the Win8.1SE taskbar. Choose Local, then Disk, then To Image. Navigate to the storage place, choose VMDK from the file type dropdown, type the filename, and begin the imaging. If it asks you for a compression method, I recommend Fast.

Once Ghost shoves the disk into an image file, move the VMDK to the computer that will host the VM. Create a new VM with the following settings:

  • "I will install the operating system later"
  • Select your OS from the lists
  • Name your VM
  • "Split virtual disk into multiple files" and set the maximum disk size to 1GB
  • "Finish"
Once the wizard closes, select the blank VM from the list and open its settings. Delete the SCSI hard disk and add a new Hard Disk device. "Use an existing virtual disk" and select the VMDK file Ghost created. Try exposing the disk to the VM as whatever type of disk it was in the real machine, but if it fails to boot, use IDE - that always seems to work.

If the machine is a server of any sort, change the Network device from NAT to a bridge.

Start the virtual machine. You're done!

VirtualBox
I'd say VirtualBox is easier to deal with than VMWare because it can handle all manner of virtual disk formats, including the very convenient VHD. You could use Ghost like in the VMWare instructions and create a VMDK, or use Disk2Vhd, which uses Volume Shadow Copy and can perform the imaging while the system is online. Start Disk2Vhd in the running OS on the target computer. Make sure "Use VHDX" is not checked and "Use Volume Shadow Copy" is checked. Choose the storage place to save the large file, choose all the volumes on your drive, and click Create. Once the imaging is complete, move the VHD to the VM host system.

Launch VirtualBox and create a new VM. Choose your OS (this is really important in VirtualBox) and configure the computing power available to the VM. Use an existing virtual disk and select the VHD file you created with Disk2Vhd. If it's a server, make sure that the network adapter is a bridge, not NAT.

If there are any problems on boot, you may need to change the hard disk controller type. It should be the same as the physical disk, or IDE if that doesn't work.

Start the virtual machine. You're done!

Sunday, December 7, 2014

Looking at Strings with VMMap

As I was perusing the Windows Sysinternals Administrator's Reference, I learned about VMMap, a Sysinternals utility that inspects the memory allocations of a running process. One of its features is the Strings dialog, which presents a list of all the text strings (including Unicode) it could find in the loaded images (e.g. EXE, DLL). You can scroll through the list to discover all the things the program could say or think about, like error messages or parseable commands.

I used it on Abiathar and was very interested by the groupings of the texts. It seems the .NET compiler places string literals from the same methods and classes together for the most part. All the possible splash screen messages were together starting at 0x0037BAD8 in the executable file, 0x0086D6D8 in the process address space (but that might move around, I'm not sure). It also sees the strings compiled into the programs and files embedded in Abiathar, like the KeenGraph executable and the game maps files. The .NET compiler seems to write the names of all the methods, even if they're declared Private.
Some strings in Abiathar, from the Level Inspector subroutine
You can download the Sysinternals Suite from its Microsoft TechNet subsite.

Saturday, December 6, 2014

Setting up Network Policy and Access Services on Windows Server with One Network Interface

I had the pleasure of configuring the Network Policy and Access Services role on a Windows Server 2008 machine a while ago. I did run into a small problem: the machine has only one Ethernet port, and the configuration wizard for NPAS wants you to select two different interfaces, one Internet-facing and one internally-facing.

(It didn't help that the initial NPAS configuration wizard was really hard to find. You have to right-click the server icon under the NPAS role and choose "Configure and Set Up", not pick it from the Action menu.)

The solution is to choose the Custom role configuration in that first wizard page. All the other combinations of installed features will ask for two different interfaces. After choosing Custom, just tick the boxes for all the features you need. All your network interfaces (the single real one, any fake virtualized ones, the loopback one, and an "internal" one) will be automatically detected and added. All non-loopback and non-internal interfaces will support NPAS, so you might need to disable it on some if you don't want it messing with your virtual machines.

Friday, December 5, 2014

Robotics [MEET] - Competition Take II

Today was the second meet of the season, and we again didn't hold high hopes for our performance. Work continued on the cardboard ball routing tubes, but we didn't attach the servo to the box because we have no lift. We have no lift because the 3D printer that we left to run last night got jammed and failed to produce the linear bearings. What it did produce was a sheet of flat domino-like things that are entirely useless as any kind of bearing.

While tinkering and messing around, one engineer discovered that a crazy arrangement of screws, nuts, C braces, and a washer performs passably as a linear bearing when a similarly crazy assembly is stuck onto the end of the channels. He worked on putting that together over the course of the meet, but it was never attached.

Our first match (which was also the first match of the night) was a total disaster. Our NXT battery was critically low because the other team needed the full battery (that we had been using) to pass software inspection. They never gave it back to us. Somehow, the simple autonomous program (that just drives forward from the ramp) vanished from the NXT, so we ran the complicated IR-involved one despite starting on the ramp. Since one of the drive motors' wires had gotten loose, the robot turned at the start, falling sideways off the ramp rather than driving down it. It did fully leave the ramp, so we got the points! Unfortunately, that fall knocked out the other motor's cable, rendering us inoperable. Our alliance partner was trying to move the tubes, but without much success. When they tried to climb the ramp, they fell off the side, but since the side of their robot that went off the ramp fell onto our disabled robot, they were fully off the floor and got the points.

It was about this time when we noticed that the real field layout was reversed from our practice field. This inconvenient fact rendered our IR-smart autonomous program entirely useless.

Despite that, we tried using the program in our second match. By sheer luck, it got really close to the kickstand, but missed it. We helped our alliance partner push tubes up the ramp, but our acrylic number plate got jostled loose. One corner fell to the floor and got jammed in the squishy mat, rendering us unable to move forward and only allowing very slow backward movement. We managed to park in the parking zone.

We used that same autonomous routine again to get down from the ramp, and it worked since we had repaired the motor connections. We tried to move the tubes to the ramp, but jammed them all into the corner and also got a big penalty for pushing one through the opposing parking zone. We did extract one tube and started to push it up the ramp. Our robot just barely got up off the floor with a push from the alliance team.

In the fourth round, we just used the stationary musical autonomous program. We pushed several tubes up the ramp and ended the game teetering on the brink with one tube and our robot partially off the flat part of the ramp. The allied team very carefully parked in the parking zone.

Our fifth and final match was a huge jam. The allied team instructed us to play defense, so we did our best to block the opposing alliance from accessing their tubes. A flood of balls and the kicked-down kickstand tripped up our robot, and we got stuck near the opposing tubes. An opposing robot tried to drive through the mess and got stuck on top of one of our front wheels. Neither of us were able to move for the rest of the match.

Our performance here was not great. I think we won only one of our five matches (the second one). We did make some progress on the linear slide system, but our capabilities were largely unchanged from the first meet.

Thursday, December 4, 2014

Robotics - Material of Champions

The robot was being tinkered with the entire three hours of this meeting, so I didn't get a chance to improve the autonomous program. Most of my time this meeting was spent watching the tinkering (trying to understand what was going on) and watching/tinkering with the 3D printer in the other room. A team member with experience operating 3D printers did some good work repairing the printer. After removing the extrusion head from the acetone bath, it was much cleaner and could actually extrude.

We then entered a period of trial-and-error with the printer bed height that took at least an hour. We had to tighten and loosen some hex screws at the corners of the glass bed to tune the height and angle, then wait for the bed and extruder to heat up again. Along the way, we also discovered a kink in the filament routing area that was stopping much of the plastic from entering the extrusion head. After all the adjustments, the printer can print our sheet of linear bearings, which should be finished in the morning. (It takes a while.)

The major feature that our robot needs before it can be useful is a lift to elevate the balls we take to the tubes. We also need a place to store the balls, so we had to put into production the cardboard box of prototypeness. It works, but looked really out of place in all the metal machinery. The aesthetics were soon repaired: a ramp from the ball intake belt to the storage box was built out of cardboard and attached with zip ties. That's some quality engineering right there.

To control the outflow of balls, we added a servo flap to that box. This is our first servo, so we had to find and mount a servo controller. The mounting was easy enough, but powering it was a challenge; the only viable mounting place was far away from the battery and on the opposite side of the robot as the Samantha module (which has to be the last device in the power chain). Since we didn't want to send cables all around and redo our existing ball of wires, we ended up jamming two wires into one socket to create parallel circuits.

There is a meet tomorrow! We'll test the servo flap controls and do some general polishing then.

Wednesday, December 3, 2014

Robotics - 3D Debugging

At this extra-long robotics meeting, we spend most of the time tinkering with that 3D printer. With some clever use of Allen wrenches and screwdrivers, we disassembled the printing head and attempted to clean it. In doing so, we extracted a large chunk of failed extrusion stuck inside it. Several components require an acetone bath to become functional again, so we should have the printer online tomorrow!

The actual robot did receive some adjustments. Its wheel that fell off yesterday was reattached, as was the ball intake belt which fell apart. The divot-producing metal channel has been filed down so as to not damage the field.

I continued work on the autonomous, but the IR beacon's battery died and we didn't have a 9V battery laying around. We did eventually go down to the local hardware store and get one, but by then there was very little time left. I did some more testing of the routines we do have, and there is really no nice way to differentiate the center assembly positions from the current testing position.

Tuesday, December 2, 2014

Robotics - Continued Autonomous

At the previous meeting, we discovered that one small metal channel on the robot sticks down too far and causes problems when going down the ramp. (It actually made a divot in the floor mat!) We worked on filing it down, for lack of a better tool.

While others worked on that and tinkered with the partially-functioning 3D printer the AEA let us borrow, I continued working on the autonomous routine. It now does an excellent job of knocking down the kickstand in Position 3 thanks to better tuning of the turn time. I also started using the nicer HiTechnic IR Seeker 1200 drivers, so I can gain even deeper insight into the IR topology and make positional decisions based on that.

The program now checks whether the IR is in place for Position 3 before blindly going ahead and ramming a pole that might be there or might be a wall. I also added pathing and detection for Position 2. Unfortunately, the IR sensor occasionally produces the same value for Positions 3 and 2 from where I'm testing, so I may need to locate another testing spot. Both paths have been tested and work excellently. All that's left is to add pathing and detection for Position 1 and maybe rework the IR checking.

On Thursday, the good builders will both be there, so we can actually add hardware to the robot.

Monday, December 1, 2014

Robotics - Autonomous Time

No builders came to this robotics meeting, which made the extra length of it somewhat pointless. We started by trying to decide what to do for our linear bearings. The original idea was to 3D-print them, and we printed one, a prototype. It works perfectly, but no 3D printer owner in the area is willing to let us mass-produce them (we need at least 35 more) for free and soonish.

One option - which we started using as an experiment - is to use Sculpy, an interesting plastic-clay substance that is squishable until it's baked in an oven, at which point it becomes hard like plastic. The problems with this are that [1] we don't have enough Sculpy to make 35 more of these bearings and [2] we aren't nearly as accurate as a 3D printer, and accuracy is important (on the mm scale).

I started looking for online 3D print shops and discovered Shapeways. We determined that the cheapest material they'll use - sandstone (yes, you read that right, we can make robot parts out of sandstone) - will cost us $150 to print all the parts we need. If we use a decent material like plastic or metal, the price rapidly increases from $210.

We still haven't decided on our plan for that. While everybody else worked on Sculpy and our display board, I started working on our autonomous routine. At the first meet, all we could do was drive down from the ramp and play music. My current goal is to get it detecting the position of the kickstand and kicking it down.

After much testing, tweaking, and robotic destruction of the field, I got a routine starting in the parking zone, moving up to test for Position 3, spinning around, and utterly destroying that kickstand if it is in fact in Position 3. The infrared isn't hooked up to this program yet, but I did modify the tele-op program to play a tone indicating the value returned from the sensor (the angle of the emitter) at the press of a certain button. We did a bunch of driving around to verify that it is in fact working and help me figure out which infrared angles to use in the checks.

Sunday, November 30, 2014

The Bare Roots Server Resets

The decision was made - not by me, actually unilaterally by the server owner - that the world of the Bare Roots server, a YouTuber-only Minecraft server of which I am a member, will be reset. This means that the current world, along with all progress in it, will be blown away and replaced with a brand new map from a different random seed. This is after just six months of content production on the current map.

I can't say I'm happy about the reset, but I'm not angry or sad. I've been away (actually I vanished completely from our group) from the server for the past two months, and I welcome the chance to get back in sync with everyone as we start building our world anew. The server owner said that this reset is also an attempt to jump-start activity in the server - I'm not the only one who's been away. Of course, map resets are not a sustainable or particularly effective means of infusing the server with activity, historically speaking, but hey, it's a try.

Attempts will be made to bring in some new characters. Three have left and one is considering; I suppose we're all busy with real life. I've heard that there will be some "gimmicks" - gameplay modifications - in the new world, but no specifics are out yet.

I recorded my final episode on this map today, just the nineteenth in the series. Hopefully, next season will last longer and I'll be able to produce more interesting content.

Saturday, November 29, 2014

FMod - Certificates Issued

Today, I was busy studying for my online courses. I did, however, issue Abiathar VeriMaps Extended Distinction certificates (that's a mouthful) to a few members of the community who contributed to Abiathar, beta testers and icon artists. The certification process is really easy: I just fire up the VeriMaps Certificate Generator console program I wrote a couple days ago, type the name of the person and their distinction (e.g. "creator of Abiathar" for me), move the public-key ACERT file to the appropriate section of my public Dropbox, and send the private-key ASIGN file's contents to the recipient via forum PM.

This system seems to have reignited some interest in modding; some people messaged me back saying that they're going to try to make use of the certificate.

Friday, November 28, 2014

FMod - v2.2

I did some more testing of the new Abiathar v2.2 features, especially VeriMaps. It works perfectly on all of Abiathar's level formats (except TED5 MapTemp/MapTHead, where it is disabled because there isn't a convenient no-op zone to put the signature). I generated a certificate for Anonymous and put it and its public verification certificate in my public Dropbox so people can experiment with VeriMaps. I also tweaked the upgrade code so that depsfiles with no default set won't get upgraded, as there is no audio support for them anyway. I also made it so the VeriMaps Signature option does not appear for people without a VeriMaps signing certificate.

I published v2.2 on the PCKF and Keen:Modding, plus the command-line VeriMaps inspection utility. I am still awaiting replies and feedback.

Thursday, November 27, 2014

FMod - Cryptographic Signature

I'm on Thanksgiving break now, and in my breaks between being thankful, I made a serious push toward the release of Abiathar v2.2. The really hard parts - the actual manipulation of music and sound - have been done for a few weeks. Today, I finished up the smooth-upgrade routine for this version, which copies the new portions of the dependency file from defaults.aconf. (It was a lot easier than I expected.)

So, I did something kind of unusual. I decided to add a means of crypto-signing the levels, which writes an encrypted hash of the main level data to the no-op zone of the gamemaps file. That way, the game can load the file without getting confused and Abiathar can do whatever it wants. The certificates for level signing will be distributed to noteworthy people in the community. Matching public keys will be placed in my public Dropbox so that the hashes can be verified.

The purpose of this setup is to let people know who modified a level set last - whether it has been modified from its original version, say, by a mirror host. It is not copy protection or edit protection; anybody is free to open a signed dependency file and save it. If they modify it, however, the signature will become invalid - or the signature of the modifier, which is easy to detect. Therefore, it can't be used to see whether somebody had the original idea for a level, just who modified it last, which can prove that it was not modified from the state intended by the last author.

I call it VeriMaps, and it's nicely integrated into Abiathar now. It looks for a VeriMaps private key file in the current directory and will use it to sign saved levels once a menu option is checked. (Hashing and signing are somewhat expensive operations.) The signature state is always displayed in the status bar. It indicates whether signing is in use, who the signature purports to be from, and whether it is authentic. (Authenticity is checked by downloading the appropriate public key from my Dropbox, all automatically.)

Finally, I thoroughly tested the audio management on all three supported episodes. It worked great on Keen 4 and 5, but I got a patch offset wrong for Keen 6. After fixing that, everything seems good! v2.2 will hopefully come out tomorrow.

Tuesday, November 25, 2014

Collecting the Plaintext Password of an Already Logged-on Windows User

In a previous post, I explained how to set up a scheduled task to nab a logging-on user's password. I said that you could kick them off their session if you wanted to use that technique when they log on again, but getting their password if they're already logged in is probably easier.

To start, you'll need WCE and PsExec. Open an elevated command prompt with permissions on the target computer (typically domain admin). Navigate to the directory containing WCE and PsExec, then type this command:

psexec \\target -s -c -f wce -w

Replace "target" with the name of the remote computer containing the user's session.

The WCE output, including the plaintext passwords of all logged-on users, will be delivered to your console in a second. That was easy!

Monday, November 24, 2014

Robotics - Post-Meet Adjustments

Using what we learned from our experience at the first meet, we started to refine our robot for the next meet, which is in just two weeks. We wrote some agenda items on the whiteboard so that we have some goals to work towards.

First, we switched the gearing so that the wheels go immensely faster than they did before. The difference is amazing, and we can do a sort-of drift effect. With the amplified speed, we discovered another hardware problem: the right wheel wasn't moving all the time. After tightening its axle hub, everything was good.

To test the driving, we had to take our main battery off the charger and re-flash the Samantha module. The former part of that posed a problem: the battery connector is immensely difficult to disconnect. When we did that, it shorted and blew the fuse. Once we replaced that, the Samantha was easily flashed and everything was good.

We also rearranged the NXT and Samantha mounts to be more easily accessible and to make room for the eventual ball hopper.

While they did all this tinkering, I made a shopping list for things we need. It includes:

  • USB A-B cable
  • Allen wrenches
  • Tetrix Flat Max metal pieces
  • Replacement fuses

Saturday, November 22, 2014

Collecting the Plaintext Password of a Logging-on Windows User

I made a passing mention to WCE a little while back, and today I found a fun use for it. Suppose you need the password for a domain account. For example, you're a domain administrator who needs to investigate a problem user quickly: breaking the SAM/NTLM hash would take a while; resetting the password would destroy encrypted files and alert the user.

If you have administrative access to a workstation on which the target user will log on, you can use the aforementioned Windows Credentials Editor to steal the plaintext password, at least on Windows 7. (Windows 8 seems to have disabled the Digest Authentication module that leaks the password.) You'll probably need to disable or add an exception to the antivirus software, or alternatively use a PE packer - WCE is regarded in some places as a hacking tool. (Makes sense.)

Using your form of admin power, be it local or domain (use the ADMIN$ or C$ share), drop the WCE executable and a batch file containing the following somewhere on the target computer:

wce -w > pwd.txt

Open MMC and add the Task Scheduler snap-in pointed at the target computer. Add a scheduled task with the following settings:

  • General tab
    • Click "Change User or Group" and select SYSTEM
    • Check "Run with highest privileges"
    • Check "Hidden" if you want to be extra sneaky
  • Triggers tab
    • Add a new trigger
      • Pull down "Begin the task" and choose "At log on"
      • Choose "Specific user", then "Change User" specifying the target account
  • Actions tab
    • Add a new action
      • Ensure "Start a program" is selected
      • "Browse" to select the batch file
  • Conditions tab
    • Uncheck "Start the task only if the computer is on AC power"
  • Settings tab
    • Uncheck "Allow task to be run on demand"
    • Uncheck "If the running task does not end when requested, force it to stop"
Save the task. When the target user next logs on, their password (and that of any other logged-on user) will be dumped to pwd.txt. If you're impatient, you can kick them off, hoping that they don't suspect anything and that they'll log right back on.

EDIT (11/25): Alternatively, you can use PsExec to grab it from an existing session immediately and silently. See the new post.

Robotics [MEET] - Piano Man

Today was the first meet of the 2014-15 FTC season. This was a qualifier meet, so it was an opportunity to advance to state (for those that did well enough). Now, I held no delusions of adequacy or expectations to do well at all, but I was looking forward to seeing what others had come up with.

I made the final revisions to the engineering notebook in study hall. I then printed it out, stuffed the pages into individual page guards, and bound them in a three-ring binder. I had to tape the cover on because there were large smudges in the cover guard. The document looked pretty good all bound together, but it turned out we didn't need it at this meet - there was no judges' interview. I am glad I did it, though, or I would have procrastinated until the next meet and there would have been even more to write.

After the normal school day, we loaded the robot, our tools, and ourselves into some faculty vehicles and drove over to another high school where the meet was held. I'd say there were about 20 teams present.

Once we got our stuff unpacked and the robot on the table, I began programming the devices that had been added after I left yesterday's meeting. The other team (6723) had added a new motor and servo as part of their ball input mechanism. They also had a continuous rotation servo, which just spun continuously because I couldn't figure out how to make it do anything else. (I didn't have Internet access, and it was spinning the right way. I think our motto for this year so far should be "it's good enough.")

While I adjusted the programming, the builders continued tinkering with the ball intake device, eventually making it support both large and small balls. They also (after some matches) added a shield to mitigate trapping due to balls under the frame.

We passed software and hardware inspection easily. When it came time for the field test, though, we discovered that our battery was critically low. Many kind teams offered to loan us their battery or the use of their charger, but we just happened to have a really weird and unique connector for our battery that literally nobody had ever seen before. Though we had another battery, its fuse was blown. After much fumbling about looking for appropriate pliers, we put the working fuse from the empty battery into the full battery. It worked, and we passed field inspection.

Previously in study hall, I had created two autonomous programs (sort of three if you count the version for team 6723): one to do nothing (if we start in the parking zone) and one to drive forward for a few seconds (if we start on the ramp). In both cases, we end up doing nothing for a good amount of time. So, I thought of something for it to do while waiting: play the piano. Using the formula for frequency of the Nth note on a piano (which I happened to have open on a Wikipedia page on my laptop before I left an Internet-connected network), I created a routine to press random keys on a virtual piano for random (short) length of time. It sounded really cool, and thoroughly entertained the other teams during the matches.

Speaking of those matches, our general strategy was to use the appropriate autonomous program, drive around defensively during the tele-op phase, and push tubes onto and park the robot on the ramp. It turns out that most of the other teams there (or at least the ones we got paired up with) were in similar situations. We avoided kicking down the kickstands - it would release balls, which trip us up and are scoring elements for the other team - and tried to prevent the opposing alliance from kicking them down.

There were several hilarious moments:

  • Completely failing to score any points and also receiving a major penalty for pushing one of our tubes into the opposing parking zone. We ended the game with a score of negative 30 and, needless to say, we lost.
  • Losing control of one of the wheels due to a motor popping out of its mount, entirely disconnecting the gears. We were completely unable to turn or go up the ramp for the rest of the match.
  • Experiencing the complete wireless disconnection of the alliance partner who was supposed to do all the actual achievement. We played music with the four buttons of my controller that were originally intended to be software gear changes. (We were also trapped by small balls stuck under our frame.)
  • Shooting a small ball across the entire field. Even though we couldn't actually put it in a tube, we figured we might as well test the mechanism in production.
We came away with 2 wins out of 5, which is considerably better than I was expecting. It wasn't a total fail, and we learned what we need to focus on - I think that constitutes a success.

Thursday, November 20, 2014

Robotics - Pre-Meet

Today was the last day before the first meet of the season. We started by fixing the ball intake device’s mount so that it can actually pick up balls. It still jams occasionally, but is usually functional, especially with small balls.

A large amount of time was taken up by fixing the cable management. One wire had gotten tangled in a gear, resulting in torn insulation and general electrical unsafety. Additionally, the motor controllers had been plugged into the wrong NXT port, which was hard to discover because those ports were under the robot and hard to service. Some additional zip ties were applied to contain the many wires.

The robot can successfully drive up the ramp despite not having four-wheel drive.


Since there is no kickstand-hitting autonomous program, the infrared sensor is useless and will probably be removed tomorrow.

We made something of an effort this part of the season, but the robot does not have much functionality. We will be able to drive down the ramp in autonomous and up it in the endgame, but we can’t do anything in the normal tele-op period (we have no ball lift). Tomorrow’s meet will be an opportunity to see designs and implementation of such a device.

Wednesday, November 19, 2014

Robotics - Tinker

Today was one of the two days left before the first robotics meet in which I expected major changes and progress to happen. Unfortunately, that was not so.

We did re-mount the NXT in such a way that it fits inside the sizing cube. The cables were rearranged to be safer and not get caught in the wheels. The infrared detector has been hooked up, but not programmed yet.

There were a bunch of people trying to adjust the ball intake device so that it can fit and move the large balls, but I do not believe they were successful. The creator of that device should be present tomorrow, so we might get it properly adjusted.

We continued trying to attach small pieces of metal to the end of extruded channels to cap them (to use as telescoping pieces in a lift), this time by soldering. It did not stick, so we're probably going back to tape, or maybe just abandoning the lift. It hit us today that unless something miraculous happens tomorrow, we're not going to have anything to show at the meet besides the ability to drive around. That might just have to be how it is - it's only the first meet of the season.

Tuesday, November 18, 2014

Robotics - Too Little Too Late

Despite the extra-long meeting today to help us prepare for the meet on Friday, very little happened. (Note to everyone: we might start making progress if people actually came to and stayed at the meetings.) We're waiting on something or other for our robot (still the 3D-printed part?), so the very few people present from my team helped the other team disassemble a questionably-constructed lift mechanism and strategically apply electrical tape to cap off channels.

I started research into an autonomous routine, and discovered something incredibly annoying. RobotC's compiler does not accept "#pragma config" entries in header files; they must be in the main C file. Therefore, I can't move the motors and sensors setup into its own header file for convenient reuse and one-stop modification. (Some external preprocessing might have to happen.)

We started attaching the infrared detector to the robot, but the height of the beacon (21 inches, 3 above the maximum height of the robot) will make autonomous programming more difficult. While considering the challenge, I helped the other team test an alternative lift, which seemed to be successful.

Monday, November 17, 2014

Robotics - Panic Panic Panic

There wasn't actually a robotics meeting today.

Here are some things our team has:
  • Partially built robot
    • Currently in violation of electric safety rules
    • Doesn't have an autonomous routine
    • Can't actually do anything beyond driving around
  • Mostly empty engineering notebook
    • Doesn't have actual content
    • Is a plain Word document
  • A competition in four days
    • Yes, four days
Panic.

Panic.

PANIC!

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

...alright, everybody calm down. I'm starting on the engineering notebook tonight. Since I've published basically all you need in an engineering notebook on this blog, filling in the content will mainly consist of copypasta and interspersing the pictures I took on my video camera. I'll do it over this week.

It will be OK. Breathe, everyone.

Sunday, November 16, 2014

PsExec Doesn't Pass the Hash

There's a rumor going around the Internet, present in several wanna-be hacking articles that PsExec (the Sysinternals tool to run processes remotely) can use an NTLM hash to authenticate to the remote computer. This is not true of the standalone tool, but the PsExec module in Metasploit can (just set SMBPass to the hash).

If you want to pass-the-hash without Metasploit, you'll need to add WCE (Windows Credentials Editor) to your toolbox. You can then use that to set your session's credentials to those of a matching account on the target computer. Once that is done, PsExec without any authentication parameters will present those credentials to the target.

Unfortunately, that doesn't matter at all, thanks to a part of UAC. Unless the account is a domain account, in which case you probably wouldn't use an NTLM hash, users logging on remotely cannot use any administrative privileges they may have. It's like they're permanently trapped in UAC isolation. This can be disabled without affecting normal UAC, but only after changing an admin-only registry setting on the target computer, which hamstrings the entire attack.

Good job, Microsoft!

Saturday, November 15, 2014

Robotics - Ours Moves Too

Next Friday is the first robotics meet of the season in which our teams will compete. We took our last opportunity to have a Saturday practice, and we made some progress.

The engineers continued mounting the ball intake belt. That took a while, but after it, they mounted the NXT and Samantha module. Cable management is a disaster, but it is currently being swept under the rug with zip ties. With all the wheels finally put on a motor and connected to the NXT, I did the programming for a basic driving routine. This was incredibly easy thanks to the tele-op header file I had made for the other team - the main .c file was only five lines of code, plus the "#pragma config" lines for the motors and sensors.

Speaking of motors and sensors configuration in the Robot-C files, I should soon move that chunk of code to a header file. That way, we can change it in one place and affect both the tele-op program and the future autonomous routine. I did already re-arrange the header files in the file system to make this workable. I also wrote up a coding conventions document which will hopefully be followed by the other programmer.

The ball intake belt works fine, but it was mounted too close to the ground to pick up the large balls. That should be easy to adjust next meeting.

The other team also has their ball input mechanism working, plus a place to store the balls. (They almost have a way to get the balls into the tubes.) They are currently waiting for the continuous-rotation servos they ordered to arrive.

Friday, November 14, 2014

FMod - Request for Complaints

After reading "This Is All Your App Is: a Collection of Tiny Details", I realized that Abiathar - as a very complex program - likely has some sub-optimal points in the UI. Therefore, I called upon the Keen modding community to complain to me about every detail so that I can make it perfect.

The result is this K:M thread. Let's improve Abiathar!

Thursday, November 13, 2014

Robotics - Attach It Better

People actually came to today's robotics meeting (shocking!), including our best engineer. It turns out that my attachment of the ball intake assembly was actually upside-down and generally shoddy, so the real builders spent today making an actual attachment.

They also replaced the bar going across the robot (that gives it stability) with a single piece of metal. Previously, it had been several short pieces bolted together. Also, they made a better battery mount and rearranged the electronics hub area.

I did some rearranging of the code, placing the bulk of the tele-op code in a header file. I added all kinds of pre-processing conditionals to select at compile-time whether it would use four-wheel drive, but all based on the same file. That one file can be used for all tele-op programs (including the other team's) because it - in the driving loop - invokes a callback function in the including file, which handles robot- or routine-specific controls.

Wednesday, November 12, 2014

Robotics - Literally Nobody

Today, there was only one other robotics person at the meeting today, and he was on the other team. He was at least a builder, so he actually was able to do some things. The other team's robot is actually going pretty well: it moves and almost has a game-specific mechanism hooked up.

I helped replace the other robot's back wheels with omni-wheels and got them hooked up to motors for four-wheel drive. While he tinkered with their ball input device, I got to work coding the four-wheel drive and improving the software gearing.

My lack of experience with C caused some issues here. It took me about a half an hour to debug a for-loop, and it turned out that my initial understanding of loops was correct. The problem was that the Robot-C joystick driver starts numbering buttons at 1, not 0 like everything else in C. After I fixed that, testing power multipliers for the "gears" was easy.

There is now a header file for dealing with four-wheel drive so that my team can easily integrate it if we choose to go with such a drive arrangement. I added that and my improvements to the software gearing to the GitHub.

Tuesday, November 11, 2014

Robotics - Attach It

The robotics team continues to be short on attendance and supplies. We're still waiting to 3D-print some important piece, but we did our best to attach the ball input belt to the robot base. Since it's diagonal, we found some L brackets and bent them to produce the appropriate angle. It turned out that [1] it's hard to bend things with pliers and stop them from just arcing and [2] we didn't actually need to destroy those L brackets. 

I suggested that we take advantage of the metal channels with 8 holes around each attachment point and simply rotate one by 45 degrees and screw it in. That would have worked, but the corner of the channel hit the channel below it. running parallel to the floor. We then discovered some short flat pieces (that were bent up for some reason), which I hammered into straightness. The attachment was then a success. It was a challenge aligning the other side, but we (down to 2 people at this point in the meeting) got it standing up and stable enough.

Monday, November 10, 2014

Robotics - Have Design

On Saturday, some members of the robotics team - not including me - went to the Putnam (local museum) machine shop to work on the robot's mission-critical parts. From what I hear, they designed and 3D-printed some things, but the printer (or possibly the CAD operator) experienced some issues and produced unusable parts. They did, however, successfully produce a design sketch for our robot.

We're still waiting on some parts, but we did do some tinkering with the robot base. The battery and motor controllers have been mounted to the new design's base and wired up. I'm waiting for the builders to mount the NXT so I can start programming the basic autonomous routine.

I tested the software-geared drive program on the other team's robot, and it worked pretty OK, but they ran out of battery. While I waited for things to happen, I continued to show the new programming assistant (who is very good with CAD) Robot-C programming concepts, using the complicated geared drive program as a real-world example.

Sunday, November 9, 2014

Windows App Paths

Some people might know about this already, but it's a cool detail of Windows that I found fascinating. Pretty much everybody knows you can type program file names into the Run dialog and have them appear, and you can add directories to the PATH environment variable to make the Run dialog search those places if you don't supply a path.

But, some applications can launch even if their executable is not on the PATH. This is through a feature called App Paths. It is a registry key that maps executable file names (non-qualified) to full paths and provides their initial directory.

There are two instances of it, one under HKLM and another under HKCU, for everyone and the current user, respectively. You can find it at HK??\Software\Microsoft\Windows\CurrentVersion\AppPaths. Each subkey is the name of a program you can type at the Run dialog.

The default value of each key is the full path to the executable. (It doesn't even have to have the same file name as the unqualified name!) The Path value provides the initial directory. There seem to be some other properties that can be set, like UseURL and BlockOnTSNonInstallMode, but I'm not entirely sure what they do.

Saturday, November 8, 2014

FMod - All the Sound

It has come to my attention that there is actually a demand for the ability to import and export all the Keen:Galaxy sounds, not just the music. In fact, the final episode of the unofficial TUIT trilogy has all-new AdLib sounds.

So, I made a good effort today to add that functionality to Abiathar. Now, Abiathar isn't intended (at this stage) to be an amazing sound editor; just dumping the sound files out and sucking them back is all I need to do. The UI is, therefore, simple. The Audio Files menu item is now a submenu with items of its own: Resources, Export, and Import. (Resources produces the Audio Files dialog.) Those new entries simply create the save-file and open-file dialogs, respectively. Those dialogs set the list file, which binds all the sound files together (holds references to their filenames and chunk IDs). The individual sound files are spewed out in the directory of the sound list file, which can be placed anywhere.

It works well: I successfully round-tripped the Keen 4 audio resources. All the metadata of the sounds (e.g. priority, OPL instrument settings) are stored in the list file on the line representing the appropriate sound. It turns out that this is not how KeenWave did it - KeenWave just takes the chunks and dumps them out without any processing, header and all. I will add a config option to produce this behavior, probably making it the default.

Since Abiathar's patch generator is becoming increasingly important, serious modders might start using it. Therefore, there should be a convenient way to add user-defined patches that Abiathar doesn't have to understand. For that, I created the Patches dialog, which presents a text box bound to a string array in the project file, integrated by the patch generator into the outputted patch file. There is a notice above the field informing the user the Abiathar handles the header/footer, map header, tileinfo, graphics files, audio files, and music mappings.

Wednesday, November 5, 2014

Robotics - Ball Input

We were reminded at today's robotics meeting that there are less than two weeks left before the first qualifying match we want to attend - and we don't even have a driving robot yet. Today, we continued our efforts to remedy that.

After the pep talk, I opened up the RobotC IDE and started teaching a new member of the team (previously on a different, non-school team) robot programming. She has never done any CS or development work, but she seems to be getting it. I think the idea of having her on the team is for her to be my assistant, but I don't really need any assistance. I'll try to continue teaching her things throughout the season.

Since having a Samantha module is very important to making the robot move, I dug out the one that wasn't working and tried again. For some reason, it worked today with the same flash drive I had tried before. Whatever the problem was, it's fixed, and we have remote communication with the robot. I wrote a tiny test program (while teaching the new recruit) that runs the first motor.

That was used to test the engineering team's almost-production-ready prototype for the ball input chute. It consists of a belt with rotating spokes in a tube. They were tinkering with it for most of the practice, and it seems to work very well now. Setting up the drive motors will be trivial; the remaining challenges are to get a good autonomous program and to actually put the balls in the high tubes.

Tuesday, November 4, 2014

Crushers - v2.5

Crushers 2.5 is here! I made all the changes I discussed in a post a few days ago and a few more. Essentially all bugs have been fixed. I think the most distinguishing feature of this update is the adaptation to widescreen - this is the first game of mine to have that update.

Download Crushers 2.5 (EXE: 4.3 MB)

Monday, November 3, 2014

Robotics - Cleaned Up

Though I wasn't at the robotics meeting on Saturday, it seems the teams were fairly productive. When I arrived, I found that the parts room had been cleared of all the miscellaneous junk everywhere; everything is now actually in a place that makes sense, near similar things. A robot frame had been constructed with a motor or two. More interestingly, though, there was an almost-production-grade prototype for ball input device.

Today, people worked on the battery mount. (At least, that was what happened in the short time I could be at the meeting. I had to go do another thing for a good deal of the time.) This is important because we have historically had issues with the battery getting jostled and disconnected. I made some adjustments to the software gearing code, but did not get a chance to test them.

Sunday, November 2, 2014

FMod - Song Success

After finding and crushing some silly off-by-one bugs, Abiathar's Music Mappings dialog loads successfully. I finished coding the buttons that actually do the work of importing IMFs and fixed a bug in the song deletion routine that caused it to sometimes not clean up all the unused ephemeral slots.



There were some problems with saving the imported song name (mojibake), but I fixed that by switching to a UTF-8 encoding and prepending the actual header byte instead of putting it inside the GetBytes call.

I also made the Audio Resources dialog a persistent configuration dialog instead of a set-up wizard. (It can load the existing configuration instead of just wiping it out.) There is now an option to dissociate the audio files from the dependency file.


With those in place, it was time to actually test the mappings. I threw random songs into Keen 4 levels, exported the patches, and it worked! I could successfully choose which song goes into which level. Then I tried adding new songs (exported by KeenWave from Keen 6). That didn't go so well - the patch file seemed to be generated correctly, but I just got silence. I got the same effect when I overwrote existing chunks with the imported songs.

It turns out that KeenWave exports Type 1 IMF files; Abiathar by default expects Type 0. So, it had been importing the files shifted by two bytes, writing (usually) zero to various undefined OPL registers. I changed the default to expect Type 1 files after doing research and determining that the commonly used MIDI to IMF converter also produces Type 1 files.

With that change made, I tested the addition of new songs again. It worked! This makes Abiathar the first program (not just level editor) to automate the process of adding new songs. v2.2 will hopefully be out in a week or so.

Saturday, November 1, 2014

FMod - Music Mapping

With a rare bit of spare time on my hands today, I went back to Abiathar to continue my work on the now long-in-progress v2.2 update that will add music import and assignment support to Abiathar.

When I had last left off, I had an audio file configuration/dumping wizard and a poorly-designed Sound Manager form. I still don't have any idea how I want to deal with non-song sounds, so I ignored that (dead code currently) and moved on to music.

For that, I created the Music Mappings dialog. It consists of a list of levels, a list of songs, and some buttons to control which song goes to each level. I coded most of the buttons, but there are still strange issues involving the actual population of the dialog. Once I get the dialog actually rendering, I can show what I've done.

Friday, October 31, 2014

Why Effective Permissions Sometimes Aren't Correct

You may have noticed that Windows's "Effective Permissions" utility (somewhere in the Security tab on files) doesn't always report what permissions you have correctly, especially if you have local admin and not domain admin. This is due to a subtlety of SIDs.

A Security IDentifier (SID), uniquely (ding ding ding! there's the key) identifies a security principal - a user, group, or special claims-based thing like TrustedInstaller. Users on a domain each have a SID and that is unique across all computers. The Administrators group (for which most files have an ACL entry), however, is not specific to a domain or computer. Its SID is always S-1-5-32-544, whether it's the Administrators group on the domain (not the Domain Admins group), the Administrators group on the file server, or an Administrators group on some random client computer.

Suppose you're a local admin on your machine and therefore a member of S-1-5-32-544 on your computer. When you hand your impersonation token over to a file server and say "hey, I'm an admin, gimme this file!", it says "alright, let me check that", consults its impression of S-1-5-32-544 (because it has a group with that SID, of course), says "hey, you're not on that list!", and denies you access.

Your computer, on the other hand, sees the ACL entry for S-1-5-32-544, says "oh cool, you're a part of that, you can have all the access." The Effective Permissions utility does not ask the remote host; it only checks the SIDs on the ACL.

There might be other ACLs you can't see, like the ones in the mini-ACL editor you get when running the Advanced Sharing wizard. Those aren't on the file system like normal ACLs; they're extra restrictions processed by the LanMan service. You might also be subjected to restrictions for situation-based principals like Network (S-1-5-2), the faux-group of people who are remotely accessing the file.

Wednesday, October 29, 2014

Robotics - Moving Around

As I'm pretty used to by now, very few people came to today's robotics meeting! We did at least have an engineer, who was tinkering with a generic frame and trying to make do with our lack of relevant parts. (We have no axle hubs, not enough motors, not the right kind of wheels, a broken Samantha module, the wrong type of battery connector, and a poorly-functioning wire stripper.) While he worked with that, I oversaw the continued assembly of the field.

We got the kickstands and ball holding chambers set up yesterday. Today, we riveted the small wooden parts involved in the mount of the high center ball tube. We would have attached the tube and the guard/wrapper/thing around it, but for some reason the instructions call for that to be done with a stapler and we couldn't find one.

More interestingly, I continued work on the other team's tele-op program. I ran a test with buttons and tones to determine whether anything involved in the joystick was being sent to the robot - it was. I tried controlling motors with buttons - it worked, but there was insufficient traction on the wheels to move with only one wheel at once. After they fixed that, I tried controlling the motors again with the thumbsticks - it produced the same strange going-in-circles effect.

After a little bit of research (looking around in the example programs), I discovered that I not only have to call getJoystickSettings(joystick), but I have to use the "joy1_y1" and company members of default "joystick" variable. I had tried both of those things individually, but apparently never together. For some reason, the joy1Btn function works even if I don't call getJoystickSettings. Anyway, I hooked the thumbsticks up to the motors again and they were able to drive.

People were very excited, so I gave everybody in attendance a few minutes to drive the robot around. One managed to accidentally trip the kickstand, releasing a flood of balls, which was pretty exciting. Once everybody had their turn, I started implementing a virtual gearing system for precise controls. Unfortunately, their NXT ran out of battery power, so testing that will have to wait until next time.

Tuesday, October 28, 2014

Fix for RobotC 3.x Not Allowing WiFi Connections

I discovered a curious bug in the RobotC development environment today, at least in version 3.62. Sometimes, especially when the user running the IDE is not an administrator, WiFi connections to the robot will not work at all. What happens is that the robot search dropdown loses the WiFi options and the box for robots found via WiFi says something to the effect of "Searching for robots via WiFi is disabled."

I found one forum post that recommended checking the "Enable Wireless Searching for NXT" under Preferences under View. I tried that, but it did not do anything to solve the problem, even after a restart. It took me quite a while to figure out a real solution.

What you need to do is find an account where RobotC does do WiFi right and export the RobotC registry tree. This is found at HKCU\Software\Robot Academy. Open the Registry Editor by opening the Run dialog and launching "regedit". Expand the "HKEY_CURRENT_USER" folder, then Software, then just select "Robot Academy". Under File, use Export to save the selected tree to disk. If you have no environment in which RobotC behaves as expected, download my version of the registry tree.

Once you have acquired a working registry configuration, log into the user account for which it is not working and merge (import) the exported .reg file into your user registry (just double-click and OK any warnings). Launch RobotC and everything should be good.

Monday, October 27, 2014

Robotics - A Riveting Tale

Once again, very few people actually came to the robotics meeting. We still don't have a robot or materials necessary to make one do interesting things, so we just continued building the field. At a meeting which I could not attend last week, they found a drill and removed the incorrect rivets from the center field assembly pipes.

We installed the correct pipes today and started attaching the other Plexiglas side of the center assembly. The first rivet we put in, it didn't actually go through into the side of the structure - only into the Plexiglas - so we had to drill it out of the Plexiglas while being careful to not shatter it. Once we got longer rivets, the attachment went well.

I did a little bit more work on the RobotC program for the other team (which at least has a robot), but it still exhibits the strange problem of not getting the joystick movements.

Sunday, October 26, 2014

Crushers - Polish That

I have been pretty stressed lately, and playing my old arcade-style game Crushers has been a really awesome way to relax. I consider it my best production, but it is currently in a state of half-brokenness because I ran out of time a few months ago while I was doing lots of updating/refactoring. With crosscountry done and another unit of communication class almost over, I want to use a little of my free time for a few days to polish Crushers.

Currently, it has a bug in which blocks are sometimes spawned not aligned to the usual 16x16 grid, which causes weird glitches, teleporting, and disappearance when they collide with another block. I have a pretty good idea of how to fix it, but it will take a little bit of time to go through the block spawning code (which needs a good refactor anyway).

Additionally, since I and pretty much everybody else have widescreen monitors (16:9 aspect ratio), there are blank black bars to the left and right of the Crushers game area. Adjusting the view properties to use a widescreen size will be trivial.

Some adjustments need to be made to the suffocation mechanic, like having the air particles track the player when he is in a 1-wide hole. It could also benefit from a dynamic grid of oxygen sources , but that's a pretty advanced programming thing.

The antigrav dimension could use some work, like being rebalanced to not be a guaranteed death trap. It could also be incentivized, maybe with some score bonuses for being in it or diminishing returns in the normal dimension.

I have other grand ideas, but for now I want to get bugs fixed and get the full v2.5 out.

Friday, October 24, 2014

Forgotten Windows Feature: Document Scraps

Up to Windows XP, there was an obscure little feature of the shell called "scraps." It is a system which, essentially, allows you to take an OLE object that supports dragging-and-dropping (and serialization) and place it in the file system as a file. These files, scraps, are even given special treatment kind of like shortcuts - extensions never seem to be shown for them (though they do have extension SHS).

They are usually generated from Microsoft Office products, by dragging selected text or objects out of the Office window and onto the desktop. They can then be dragged in later to a different document, or double-clicked like normal files to launch the owning application and paste the contents into the new window.

You can read the Microsoft KB article for the official information.

Monday, October 20, 2014

Robotics - Design Day

Today's robotics meeting did not involve a lot of robotics. Instead, we were in the upper school computer lab to work on the engineering notebook and T-shirt designs. I made a little more progress on the notebook; it is going slowly, though. The other designers dug up last year's shirt design and adapted it to have our names on it. This is good - I liked the old design.

We really need to get back to robot building.

Sunday, October 19, 2014

Windows 95 Network Fonts Folder Bug

While transferring files from a Windows 95 machine to a Windows 95 VM, I discovered a very curious bug. I needed to grab all the fonts from the machine and put them in the VM, so I used Explorer to access the machine's fonts folder via LanMan. The two computers appeared to have the exact same set of fonts when I looked at it on one screen (one window at the local folder and one on remote), but the real machine had far more when I looked at its fonts folder at the real workstation.

I accessed the VM's fonts folder over the network from the real machine, and it showed the same fonts on both computers - but with an entirely different and much larger set of fonts! Apparently, accessing any folder that is configured via desktop.ini to be the Fonts folder will produce the Fonts dialog without regard for which computer it is on.

The workaround was to copy all the font files over via a command prompt, which doesn't do any special shell-folders stuff.

Saturday, October 18, 2014

What's up with the big air blocks in Minecraft oceans?

If you've played Minecraft for a while and gone adventuring on the high seas, you may have noticed an unusual phenomenon in large bodies of water. Large rectangular-prism pockets of air may sometimes generate a few blocks on or under the ocean surface.

These appear when abandoned mineshafts have generated or attempted to generate under the ocean floor. The air pockets would have been filled by an "entrance" to the mineshaft had there been the right type of blocks there.

All structure generation is canceled by the presence of liquid within a component's bounding box, but the critical/initial parts do execute some generation routines. For example, the End portal room of a stronghold will generate wherever it tries to, though it might be alone if other potential components intersect standing liquids. Evidently, the block-clearance code for mineshafts executes before the liquid check, resulting in the strange air bubbles.

Thursday, October 16, 2014

Robotics - Wi-Fi Time

As in all Thursdays, today's robotics meeting was extended from its normal length of 90 minutes, this time to a full three hours! (Fortunately, there was pizza.) I finally started on the engineering notebook, taking advantage of my nice video-and-image camera to photograph the sketches on the whiteboards. 

I also took some time to read over the engineering notebook section of the rulebook, and also went through the official FTC Forum's question-and-answer section. When a question is asked there that requests a rule clarification, the response from the FTC officials is essentially added to the rulebook. Unfortunately, it's spread out all over a bunch of forum threads and not centralized very well, so basically rules are constantly being created and I don't have a convenient way to know about them.

The box-with-flap idea continued its development. The team captain attached a servo to the box and constructed a frame for the assembly, which will be combined with another design by a different builder.

Builders from the school's other team asked me to help them program their robot. They don't have a programmer, and I didn't have anything else to do, so I started hooking up their robot with some functionality. First, we needed wireless connectivity. The Samantha module that I couldn't get to power on previously worked on their robot (I guess the battery I was using is bad), but it refused to accept configuration from the USB drive - it would do the light cycle like it was updating, but would always go to a random unsecured network instead of the one I told it about.

It turns out there were two problems. One: the Samantha module was bad. Two: the flash drive I was using had too much capacity. The Samantha bootloader can only address 4GB of hard drive space and will be very confused if there is more. Fortunately, there was a 2GB drive laying around.

With everything connected, I moved on to writing some code. Since all they had connected to the robot was the driving motors, the code was extremely simple. However, it didn't work well at all - the joystick controls don't seem to have any effect. It works as expected when I hard-code motor power values, but passing in joystick values makes the robot go in circles slowly or do nothing at all, depending on whether I epsilon'ed the value.

I did discover that I have to call getJoystickSettings (or something like that) on the "joystick" object, but even that doesn't seem to help. I'll have to keep looking in the configuration - something has to be wrong with the controller setup.

Tuesday, October 14, 2014

Robotics - Scoop Design

Some people actually came to today's robotics meeting! (Well, two more than yesterday. It's something. At least one of them was a builder/engineer.) I wrote all the ways to score points on the board so we can start planning which goals to go after, but without a basic robot we can't really test anything to see what's possible.

The team captain (who is a builder) showed me a design sketch for the scooping mechanism for the balls. It has two servos: one to flap its lid (which is also a shovel-like thing) and another to flip the entire box-like assembly up for elevation. The assembly will probably be elevated with a linear slide for dumping into the rolling goals. He also had some ideas for a light little channel to attach to the box assembly to extend its reach.

We don't have a drill yet, so removing those misplaced rivets is not currently feasible. The coach said he would bring a drill on Thursday, we should be able to finish up field construction then. I continued my attempts to power on the Samantha module, but I believe the battery with which I am trying to power it is faulty despite it turning on the LED in the motor controller. In the meantime, I will take on the role of engineering notebook compiler.

Monday, October 13, 2014

Robotics - Oops

There were extremely few people from my team at the robotics meeting today (despite almost the entire other team being there), so we did not accomplish much. I did pull out the instruction manual for the center field assembly, then tried to continue the assembly with the help of the only other person on my team present.

We got to the part in the instructions where it says to place the ball holder, but we couldn't understand how to screw it in. When we found the holes for doing so, we noticed that the pipes that were holding the upper part stiff were in the way. Then, to our dismay, we discovered that the instructions mentioned an entirely different set of pipes when it told us to push them through the center slope's holes. We had been using the kickstand pipes, which were obviously far too long! To make it even worse, the other builders had drilled holes in those pipes to line up with the holes on the side - and then riveted the kickstand pipes to the inside wall! The short pipes that were intended for bracing already had holes.

We'll need to figure that out when we get a drill. In the meantime, I installed Git for Windows onto my school laptop and successfully authored a commit to GitHub using it. This source control thing works fairly well.