Wednesday, August 12, 2015

dtrace newbie HOWTO: listing providers AND structures

One of the first things that I wanted to learn about dtrace was the answer to the question: "How do I figure out where I can put hooks to trace system activities?"

This is accomplished with 'dtrace -l', which lists all the possible providers to which dtrace scripts can be attached.

Once you find a provider of interest, e.g. io:::start(), you can again use the list (-l) option to take a peek into the kind of data that is accessible to you:

# dtrace -lvn io:::start

   ID   PROVIDER            MODULE                          FUNCTION NAME
62099         io            kernel                                   start

    Probe Description Attributes
        Identifier Names: Private
        Data Semantics:   Private
        Dependency Class: Unknown

    Argument Attributes
        Identifier Names: Private
        Data Semantics:   Private
        Dependency Class: ISA

    Argument Types
        args[0]: struct bio *
        args[1]: struct devstat *


The next logical question is, "What is in struct bio? What is in struct devstat?"

You could find the answer by grepping through /usr/include/sys. However, there's a much faster way to find out what you can look at. This is the critical piece of information that I couldn't find in other HOWTO manuals on the Internet:

# dtrace -qn 'io:::start{print(*args[0]); exit(0); }'

struct bio {
    uint8_t bio_cmd = 0x2
    uint8_t bio_flags = 0
    uint8_t bio_cflags = 0
    uint8_t bio_pflags = 0
    struct cdev *bio_dev = 0
    struct disk *bio_disk = 0xfffff80012144000
    off_t bio_offset = 0x116948cb000
    long bio_bcount = 0x1000
    caddr_t bio_data = 0xfffffe0005ada000
    struct vm_page **bio_ma = 0
    int bio_ma_offset = 0
    int bio_ma_n = 0
    int bio_error = 0
    long bio_resid = 0
    void (*)() bio_done = kernel`g_disk_done
    void *bio_driver1 = 0
    void *bio_driver2 = 0
    void *bio_caller1 = 0
    void *bio_caller2 = 0
    struct bio_queue = {
        struct bio *tqe_next = 0
        struct bio **tqe_prev = 0
    }
    const char *bio_attribute = 0
    struct g_consumer *bio_from = 0
    struct g_provider *bio_to = 0
    off_t bio_length = 0x1000
    off_t bio_completed = 0
    u_int bio_children = 0
    u_int bio_inbed = 0
    struct bio *bio_parent = 0xfffff8018178f2e8
    struct bintime bio_t0 = {
        time_t sec = 0x24d28
        uint64_t frac = 0x4543b859cc1368f0
    }
    bio_task_t *bio_task = 0
    void *bio_task_arg = 0
    void *bio_classifier1 = 0
    void *bio_classifier2 = 0
    daddr_t bio_pblkno = 0x8b4a4658
}


Now, THAT was easy!

Tuesday, August 11, 2015

Fixing a rogue Windows 7 Out of Box Experience (OOBE)

I just finished reinstalling Windows 7 OEM on a PC. The result was that the installation failed to work correctly, leaving me in a "reboot loop," because my hardware vendor included the wrong device driver for my keyboard on the installation medium.

The solution?

  1. Press SHIFT-F10 after the error box to open up a "cmd" prompt.
  2. Execute regedit.exe
  3. Navigate to HKEY_LOCAL_MACHINE\SYSTEM\Setup
  4. Delete value for CmdLine
  5. Change value to zero for OOBEInProgress, RestartSetup, SetupPhase, and SetupType.

I later had to enable the Administrator account (see previous blog post).

Windows 7: Administrator account is disabled. What now?

I recently had some problems with a Windows 7 installation gone bad that required some trickery that left the system in a place where no user accounts were created, and the Administrator account was disabled. I could, therefore, only restart the computer.

The trick to solving the problem was to hit F10 to bring up the NTLDR advanced boot options prompt (for some reason, F8 to start Safe Mode did not work).

I found this handy list of boot options that allowed me to boot into safe mode and enable the Administrator account:
  • At the F10 prompt, I typed /SAFEBOOT:NETWORK to enable Safe Mode with Networking.
  • Once the machine booted, I used a cmd prompt as administrator, and typed:
  • net user administrator /active:yes

Other boot options that I noticed might be of interest:
  • /MININT - Starts the Windows Pre-installation Environment


I forgot my password, so here's a script...

gnome-keyring is what a lot of Linux / UNIX desktop environments rely upon in order to save passwords. Here's a script that dumps the contents of the gnome-keyring. It requires the gnomekeyring python module.

Special thanks to Michael Schurter for the majority of this code. I added two small improvements and deleted some dependencies.

#!/usr/bin/env python2

import getpass
import gnomekeyring

def dump_pass():
    gnomekeyring.unlock_sync(None, getpass.getpass());
    for keyring in gnomekeyring.list_keyring_names_sync():
        for id in gnomekeyring.list_item_ids_sync(keyring):
            item = gnomekeyring.item_get_info_sync(keyring, id)
            print '[%s] %s = %s' % (
                    keyring, item.get_display_name(), item.get_secret())
        else:
            if len(gnomekeyring.list_item_ids_sync(keyring)) == 0:
                print '[%s] --empty--' % keyring

if __name__ == '__main__':
    dump_pass()

Saturday, August 8, 2015

Forcing a Windows 10 upgrade in an iSCSI environment

If you boot Windows machines from iSCSI, you should know that the Windows 10 Upgrade doesn't load iSCSI drivers and dumps you into a recovery environment. However, there is a way to get around that.

Once the Windows 10 recovery environment (Windows PE) boots, use the Advanced Options to obtain a command line.

To start the iSCSI initiator:
wpeutil initializenetwork
net start msiscsi
iscsicli qaddtargetportal portal.ip.address.here
iscsicli listtargets
iscsicli qlogintarget iqn.xxx.xxx
iscsicli PersistentLoginTarget T * * * * * * * * * * * * * * * 0 (that was fifteen * characters)
iscsicli ListPersistentTargets
iscsicli ReportTargetMappings
Once this is ready, you can manually install Windows 10:
 c:\$Windows.~WS\Sources\Windows\sources\setuperror.exe
For reference, here are the hidden upgrade folders and their meanings:
"Windows.WS = Windows Server Folder"
"Windows.BT = Windows Backup Files"
"Windows.Old = Windows backup files"

Have fun!

Sunday, August 2, 2015

How to delete the recovery partition in Windows 8 / 10

I purchased a (cheap) Asus X205TA laptop that has an integrated "32 gigabyte" SSD. Unfortunately, this computer came with a 10 gigabyte recovery partition which lopped off one third of the computer's storage capacity. One third of the device's drive capacity for a function that I will probably use once during the laptop's life? There must be a solution.

UPDATE 8/3: Apparently in Windows 8/8.1, Acer and other vendors use a tool called "WIMBOOT" which uses files stored in the recovery partition to boot your main system (although, surely your machine doesn't require 10gb of data to start up every time). The solution? Upgrade to Windows 10, and "Back up system files" as described below.

DISCLAIMER: BACK UP YOUR DATA FIRST. The following directions may result in irreversible filesystem corruption, particularly if you make a typo. I recommend using any commercial or free drive imaging software prior to following these instructions, and offer no support or warranty if disaster strikes.

Microsoft's documentation seems to indicate that it is possible to delete the recovery partition from your PC as an option when creating a USB recovery disk. However, this did not work on my machine. Fortunately, there is a solution; however, it involves a few "advanced" steps that include using a command-line tool called diskpart:
  1. Obtain a > 4GB USB drive
    Windows needs just under 4 GB to create a recovery drive for your machine. Technically, this step isn't required if you allowed your PC to automatically upgrade from Windows 7 / 8 to Windows 10 as you can use Microsoft's Media Creation Tool.

  2. Create a recovery drive
    Use the media creation tool above, or (even easier) type "Create a recovery drive" in the Start menu's search box. Make sure you choose "Back up system files" in Windows 10 when creating your recovery media.
  3. Boot from the recovery drive:
    1. Type "Change advanced startup options" in the Start menu search area
    2. Under "Advanced startup," press the "Restart Now" button.
    3. Click the "Use a device" icon
    4. Select the option that corresponds to the removable device that you made into a recovery drive to boot
  4. Obtain a command line and launch diskpart:
    1. Choose your keyboard layout
    2. Under "Choose an option," select "Troubleshoot"
    3. Under "Troubleshoot," choose "Advanced options"
    4. Under "Advanced options," choose "Command Prompt." A big black box appears.
    5. Type diskpart and hit enter.

    NOTE: The following directions assume that the "Rescue" and "Primary" partitions are next to each other; i.e. Rescue is Partition 4, and Primary is Partition 3. If this is not the case, you should STOP HERE and use something like Partition Magic or gparted to do the job.
  5. Delete the recovery partition
    1. type: list disk
    2. The resulting list will probably have your system's disk as "Disk 0." Look at the Size column to figure out if it corresponds to the size of your internal drive.
    3.  type: select disk x, where X is the disk # of your system's internal drive.
    4. type: list partition. Look at the "Type" column for a "Rescue" partition (the size should be ~ 10 GB).
    5. type: select partition x, where X is the partition # of your system's rescue partition.
    6. WARNING: the following step will delete the partition. Double-check your work.
      type: delete partition
  6. Resize the "primary" (system) partition and filesystem
    1. Consult the results from list partition and type: select partition y, where Y is the partition # that corresponds to the "Primary" system partition (it should be the biggest partition, by size).
    2. type: extend
    3. type: extend filesystem
    4. type: exit and hit enter, then type exit again. The command prompt window should close.
    5. type: list partition. You should see that your "Primary" partition is now much bigger. Hooray!
  7. Reboot into Windows
    1. Under "Choose an Option," click Continue (boot into Windows)