3

I have a defective version of bzr which I invoked using python -m pdb $(which bzr) ... to find out what the defect is.

The defect is inside a certain module and I'd like to work around the defect by executing a command right before the python binary starts interpreting the contents of $(which bzr) (which of course is a Python script itself).

Is there a way to smuggle in code right before the script is executed? I.e. as if my smuggled in code was at the top of said script file ...

The point here is that I want to be able to use the workaround without being able to write to the bzr "binary" in question (non-root).


Attempt of a comparison

NB: please do not take the following comparison to literal. The issue with the bzr module is not a missing function. The problem is more subtle and requires reloading sys plus some other stuff.

In terms of Bash imagine the faulty script to be:

#!/bin/bash
missing_function TEST

the function does not exist, so invoking the script yields:

$ ./faulty.sh
./faulty.sh: line 2: missing_function: command not found

However, if I want to be sneaky, I can abuse source or declare the function like this in an alternative file fixed.sh:

#!/bin/bash
function missing_function
{
        echo "$@"
}
source ./faulty.sh

Executing this, yields a more meaningful result:

$ ./fixed.sh
TEST

Is there a similar technique for Python or can I somehow leverage the -m <module> option for the purpose, by hijacking a script similar to how pdb seems to do it?

How would I go about it?

0xC0000022L
  • 20,597
  • 9
  • 86
  • 152
  • If its defective, why not upgrade? Also, how is it defective? Does bazaar fail as soon as its imported? –  May 29 '14 at 03:29
  • @LegoStormtroopr: easy, because there is **no** *fix* for it as of yet, so I need to *work around* the defect. No `bzr` fails while the module performs its actions. I have written a hook (`pre_command`) to work around the problem for now, but the question has still relevance to me, because not all programs will provide such hooks. – 0xC0000022L May 29 '14 at 04:08
  • **If you've found a critical bug** in bazaar, then you need to [**lodge a bug** with Canonical around the issue](https://bugs.launchpad.net/bzr) and see if they can fix it. If it impacts you as a user, more than likely others are impacted as well. This isn't a code problem technically, but a software and end user problem. Trying to hot-fix code without making changes to the actual file is fraught with issues. –  May 29 '14 at 04:29
  • @LegoStormtroopr: that has been done. The retaliative downvotes are a tad bit childish, but heck, I don't really care enough. Peace! – 0xC0000022L May 29 '14 at 04:31

2 Answers2

2

See my example below.

In faulty.py:

print 'calling missing_function'
missing_function()

In fixed.py:

def missing_function():
    print 'missing'
execfile('faulty.py',  {'missing_function' : missing_function})
fwu
  • 359
  • 2
  • 10
  • This is the way to do it. Thanks. – 0xC0000022L May 29 '14 at 04:20
  • If you are going to hot fix an executable (which I don't recommend), at least [lodge a bug with the developers](https://bugs.launchpad.net/bzr) with the relevant tracebacks and a potential solution. –  May 29 '14 at 04:23
0

The simplest thing is to just change the bzr module, but then you have to remember the changes you made if you upgrade, which is a terrible thing to need to do.

The second simplest thing I can think of is to write a script that sets up the environment that bazaar needs and then calls whatever function that is the bzr entry point. You could call it 'mybzr.py' and use it by calling python -m mybzr

Skeleton contents of mybzr.py:

if __name__ == '__main__':
    # Do whatever stuff you wanted to do to change bazaar's environment.
    # You might need to alter sys.path so that you can `import bzr`.
    import bzr
    bzr.main() # I don't actually know what the function is called...

This is only a rough outline, since I don't actually know anything about bazaar. Hopefully it's a little bit helpful.

Cody Piersall
  • 8,312
  • 2
  • 43
  • 57
  • Unfortunately `bzr` doesn't like being imported as a module. At the bottom you'll find: `raise ImportError("The bzr script cannot be imported.")` – 0xC0000022L May 29 '14 at 04:06